I have problem about many-to-many mapping.
[Case]
- Account owns Community(owner)
- Community has many Account(members)
GORM create four tables:
- ACCOUNT
- COMMUNITY
- COMMUNITY_MEMBERS
- COMMUNITY_OWNER
GORM creates a table "COMMUNITY_OWNER (ACCOUNT_ID, OWNER_ID)". Why GORM creating this?
This table is not used.(Please look at Hibernate log) I want GORM to not create COMMUNITY_OWNER. My mapping is wrong?
Related Question: cascade delete with many-to-many mapping in Grails
[Domain Class]
class Account {
String name
static hasMany = [communities: Community]
static belongsTo = [Community]
}
class Community {
String name
Account owner
static hasMany = [members: Account]
static mapping = {
owner cascade: 'none'
}
}
[TestCode]
def admin = new Account(name: 'admin').save(flush:true)
def user = new Account(name: 'user').save(flush:true)
def c = new Community(name: 'TestCommunity')
c.owner = admin
c.addToMembers(admin)
c.addToMembers(user)
c.save(flush:true)
c.removeFromMembers(user)
c.save(flush:true)
c.delete(flush:true)
[Hibernate Log]
INFO hbm2ddl.SchemaExport - Running hbm2ddl schema export
DEBUG hbm2ddl.SchemaExport - import file not found: /import.sql
INFO hbm2ddl.SchemaExport - exporting generated schema to database
DEBUG hbm2ddl.SchemaExport - drop table account if exists
DEBUG hbm2ddl.SchemaExport - drop table community if exists
DEBUG hbm2ddl.SchemaExport - drop table community_members if exists
DEBUG hbm2ddl.SchemaExport - drop table community_owner if exists
DEBUG hbm2ddl.SchemaExport - create table account (id bigint generated by default as identity, version bigint not null, name varchar(255) not null, primary key (id))
DEBUG hbm2ddl.SchemaExport - create table community (id bigint generated by default as identity, version bigint not null, name varchar(255) not null, owner_id bigint not null, primary key (id))
DEBUG hbm2ddl.SchemaExport - create table community_members (community_id bigint not null, account_id bigint not null, primary key (community_id, account_id))
<<Why create?>>
DEBUG hbm2ddl.SchemaExport - create table community_owner (account_id bigint not null, owner_id bigint not null)
DEBUG hbm2ddl.SchemaExport - alter table community add constraint FKA7C52FE92BBE477B foreign key (owner_id) references account
DEBUG hbm2ddl.SchemaExport - alter table community_members add constraint FK5A8DA6C3C4A6EE81 foreign key (community_id) references community
DEBUG hbm2ddl.SchemaExport - alter table community_members add constraint FK5A8DA6C398BAC5C1 foreign key (account_id) references account
DEBUG hbm2ddl.SchemaExport - alter table community_owner add constraint FK12E232DD98BAC5C1 foreign key (account_id) references account
DEBUG hbm2ddl.SchemaExport - alter table community_owner add constraint FK12E232DD8BE4BF77 foreign key (owner_id) references community
INFO hbm2ddl.SchemaExport - schema export complete
<<community_owner not used>>
DEBUG hibernate.SQL - insert into account (id, version, name) values (null, ?, ?)
DEBUG hibernate.SQL - insert into account (id, version, name) values (null, ?, ?)
DEBUG hibernate.SQL - insert into community (id, version, name, owner_id) values (null, ?, ?, ?)
DEBUG hibernate.SQL - update account set version=?, name=? where id=? and version=?
DEBUG hibernate.SQL - update account set version=?, name=? where id=? and version=?
DEBUG hibernate.SQL - insert into community_members (community_id, account_id) values (?, ?)
DEBUG hibernate.SQL - update account set version=?, name=? where id=? and version=?
DEBUG hibernate.SQL - update community set version=?, name=?, owner_id=? where id=? and version=?
DEBUG hibernate.SQL - delete from community_members where community_id=? and account_id=?
DEBUG hibernate.SQL - delete from community_members where community_id=?
DEBUG hibernate.SQL - delete from community where id=? and version=?
Looking at your mapping, I believe your case is slightly off (as well as the mapping). Did you mean to say ...
this would be a true many-to-many. Also from your mapping, I'm assuming you'd like Account to be the owning side of the many-to-many. If this the case, then you can do something like the following.
NOTE: the
belongsTo
in Community assumes Account will be the "owner". The mappedBy is needed otherwise Grails will blow up (here's a discussion about it).You'll end up with the Account and Community tables and a third mapping table - no fourth table.