我使用grails 2.0.0。我有三个对象Member,Product和ProductType。会员有很多产品,是一对多的关系。产品指向ProductType(参考表)并且是多对一关系。我的问题是删除产品。它适用于一种情况,而不适用于另一种情况。继续阅读。
下面映射的粗略轮廓:
Member.groovy:
class Member {
Long id
....
SortedSet products
static hasMany = [products:Product]
static mapping = {
table 'T_MEMBER'
id column:'MEMBER_ID'...
products cascade: "all-delete-orphan"
}
}
Product.groovy:
class Product {
Long id
ProductType productType
...
static belongsTo = [member:Member]
static mapping = {
table 'T_PRODUCT'
id column:'PRODUCT_ID'
member column: 'MEMBER_ID'
productType column: 'PRODUCT_TYPE'
...
}
}
ProductType.groovy:
class ProductType {
Long id
..
static mapping = {
table 'T_PRODUCT_TYPE'
id column:'PRODUCT_TYPE', generator:'assigned'
...
}
}
我得到的客户服务代码概述了......
if((newMember.products) && (newMember.products.size() >0)) {
def addList = newMember.products - existingMember.products
def removeList = existingMember.products- newMember.products
removeList.each { product ->
existingMember.removeFromProducts(product)
}
addList.each {product ->
existingMember.addToProducts(product)
}
}
到目前为止一切顺利。这很完美。但是,当我通过执行以下操作为T_PRODUCT表引入复合主键时:
static mapping = {
table 'T_PRODUCT'
//id column:'PRODUCT_ID'
id composite:['member', 'productType']
member column: 'MEMBER_ID'
productType column: 'PRODUCT_TYPE'
...
}
我明白了:
org.hibernate.StaleStateException:批量更新返回批量更新 来自update [0]的意外行数;实际行数:0;预期:1 org.hibernate.StaleStateException:批量更新返回意外 来自update [0]的行计数;实际行数:0;预计:1点 ProductService.cleanUpGorm(ProductService.groovy:442)at ProductService.maintainProduct(ProductService.groovy:213)at ClientService $ _maintainMembers_closure5.doCall(ClientService.groovy:158) 在ClientService.maintainMembers(ClientService.groovy:152)at ClientService.processMembers(ClientService.groovy:394)
知道我可能会出错吗?
答案 0 :(得分:6)
您的产品域类必须实现Serializable
并覆盖方法hashCode()
和equals()
,这一点必须在您使用复合键的情况下完成。
您的产品域类必须是这样的
class Product implements Serializable {
Long id
ProductType productType
...
static mapping = {
table 'T_PRODUCT'
id composite:['member', 'productType']
member column: 'MEMBER_ID'
productType column: 'PRODUCT_TYPE'
}
boolean equals(other) {
if (!(other instanceof Product )) {
return false
}
other.member== member && other.productType== productType
}
int hashCode() {
def builder = new HashCodeBuilder()
builder.append member
builder.append productType
builder.toHashCode()
}
}
我认为这样一切都会好的。
如果出现问题,请写。
答案 1 :(得分:1)
我强烈建议您阅读Grails doc, 5.5.2.5 Composite Primary Keys。他们确实指出了你不尊重的以下内容:
Serializable
接口并覆盖equals()
和hashCode()
方法,使用复合键中的属性进行计算。也许它可以帮助你找到正确的方向。