So, we have a many-to-many relationship between Customer and Role, set up as:
Customer {
static hasMany = [roles: Role]
}
Role {
static hasMany = [customer: Customer]
static belongsTo = Customer
}
The Role object has only a name and a set of permissions. We don’t want to cascade saves from Customer -> Role, as Role should only get modified directly.
I added:
static mapping = {
roles cascade: 'none'
}
but, whenever, I create a customer, the role table gets updated as well. Nothing changes, except that the version number is incremented.
Am I missing something else that needs to be set … is there a bug with how many-to-many relationships and cascades are set in Grails … or is there some other way I can prevent roles from being updated every time?
I usually map the join table as a domain class to avoid this issue and others (collection loading performance, optimistic locking errors, etc.) This involves removing the
hasManyandbelongsToand creating aCustomerRoledomain class:The mapping block configures the generated DDL so it’s the same as what you have now, so you won’t need to make any database changes. The static helper methods aren’t required but are convenient to hide the process of granting and revoking roles.
You will need to change you code. Since there’s no
hasMany, you can’t usecustomer.addToRoles(...). Instead to grant a role just create a new CustomerRole instance using thecreatemethod and to revoke, delete the instance using theremovemethod.The updated Role class would be
and the updated Customer class would be
This has a convenience method
getRoles()which mimics therolescollection that’s created for you by thehasManysince you will still need an easy way to access a customer’s granted roles.