Rev*_*nzo 3 grails many-to-many hibernate-cascade
因此,我们在客户和角色之间建立了多对多的关系,设置为:
Customer {
static hasMany = [roles: Role]
}
Role {
static hasMany = [customer: Customer]
static belongsTo = Customer
}
Run Code Online (Sandbox Code Playgroud)
Role对象只有一个名称和一组权限.我们不希望从Customer - > Role级联保存,因为Role只能直接修改.
我补充说:
static mapping = {
roles cascade: 'none'
}
Run Code Online (Sandbox Code Playgroud)
但是,每当我创建客户时,角色表也会更新.除了版本号增加外,没有任何变化.
我是否遗漏了需要设置的其他内容...是否存在Grails中设置了多对多关系和级联的错误...还是有其他方法可以阻止角色每次都更新?
我通常映射连接表的域类以避免此问题和其他人(集合装载性能,乐观锁定错误等),这包括切除hasMany和belongsTo和创建CustomerRole域类:
import org.apache.commons.lang.builder.HashCodeBuilder
class CustomerRole implements Serializable {
Customer customer
Role role
boolean equals(other) {
if (!(other instanceof CustomerRole)) {
return false
}
other.customer?.id == customer?.id &&
other.role?.id == role?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (customer) builder.append(customer.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static CustomerRole get(long customerId, long roleId) {
find 'from CustomerRole where customer.id=:customerId and role.id=:roleId',
[customerId: customerId, roleId: roleId]
}
static CustomerRole create(Customer customer, Role role, boolean flush = false) {
new CustomerRole(customer: customer, role: role).save(flush: flush, insert: true)
}
static boolean remove(Customer customer, Role role, boolean flush = false) {
CustomerRole instance = CustomerRole.findByCustomerAndRole(customer, role)
instance ? instance.delete(flush: flush) : false
}
static void removeAll(Customer customer) {
executeUpdate 'DELETE FROM CustomerRole WHERE customer=:customer', [customer: customer]
}
static void removeAll(Role role) {
executeUpdate 'DELETE FROM CustomerRole WHERE role=:role', [role: role]
}
static mapping = {
id composite: ['customer', 'role']
version false
table 'customer_roles'
}
}
Run Code Online (Sandbox Code Playgroud)
映射块配置生成的DDL,使其与您现在拥有的相同,因此您无需进行任何数据库更改.静态帮助程序方法不是必需的,但可以方便地隐藏授予和撤消角色的过程.
您需要更改代码.由于没有hasMany,你不能使用customer.addToRoles(...).而不是授予角色只需使用该create方法创建新的CustomerRole实例并撤消,使用该remove方法删除实例.
更新的Role类将是
class Role {
}
Run Code Online (Sandbox Code Playgroud)
并且更新的Customer类将是
class Customer {
Set<Role> getRoles() {
CustomerRole.findAllByUser(this).collect { it.role } as Set
}
}
Run Code Online (Sandbox Code Playgroud)
这有一种方便的方法getRoles(),可以模仿roles为您创建的集合,hasMany因为您仍然需要一种简单的方法来访问客户授予的角色.
| 归档时间: |
|
| 查看次数: |
2108 次 |
| 最近记录: |