问题描述
我很难将孩子从协会中删除。我正在使用 Grails 4.0.3。 有问题的两个类如下:
购物车:
class ShoppingCart implements Serializable {
private static final long serialVersionUID = 1
long id //don't think this is needed since I have a composite id below
User user
Store store
SortedSet<ShoppingCartItem> items
static hasMany = [items: ShoppingCartItem]
static constraints = {
user nullable: false
store nullable: false
}
static mapping = {
id composite: ['user','store']
items cascade: "all-delete-orphan"
}
}
和 ShoppingCartItem:
class ShoppingCartItem implements Comparable<ShoppingCartItem>,Serializable {
private static final long serialVersionUID = 1
long id //don't think this is needed since I have a composite id below
static belongsTo = [shoppingCart: ShoppingCart]
Product product
int quantity = 0
BigDecimal purchasePrice
Date lastItemAdded
static constraints = {
product nullable: false
purchasePrice nullable: false
lastItemAdded nullable: false
}
static mapping = {
id composite: ['shoppingCart','product']
}
int compareto(ShoppingCartItem otherItem) {
lastItemAdded.compareto(otherItem.lastItemAdded)
}
}
因为我有一个双向关系(在 ShoppingCartItem 中使用belongsTo)并且ShoppingCart 有一个复合键,所以我的shopping_cart_item 表如下所示:
'shopping_cart_user_id','bigint(20)','NO','PRI','',''
'shopping_cart_store_id',''
'product_id',''
'version',''
'date_created','datetime',''
'last_updated',''
'quantity','int(11)',''
'purchase_price','decimal(19,2)',''
'last_item_added',''
我有很多时间试图删除购物车项目。我已将 https://spring.io/blog/2010/07/02/gorm-gotchas-part-2/ 通读了好几遍,这对我来说很有意义,但我没有成功。
在 grails 服务方法中,我正在执行以下操作:
def updateCountInCartForProduct(ShoppingCart cart,Serializable productId,int newQuantity) {
def product = productService.get(productId)
def cartItem = cart.items.find { it.product == product }
if ( cartItem ) {
if ( newQuantity == 0 ) {
cart.removeFromItems(cartItem) // <-- this line throws the error
} else {
cartItem.quantity = newQuantity
cartItem.save()
}
}
}
12/22/2020 07:48:00 - ERROR [org.hibernate.internal.ExceptionMapperStandardImpl]: HHH000346: Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1]
12/22/2020 07:48:01 - ERROR [org.grails.web.errors.GrailsExceptionResolver]: StaleStateException occurred when processing request: [POST] /shop/updateCartQuantity - parameters:
productId: 7
newQuantity: 0
Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
打开 sql 日志记录后,我看到一些对我来说似乎很奇怪的东西:
12/22/2020 07:48:00 - DEBUG [org.hibernate.sql]: delete from shopping_cart_item where shopping_cart_user_id=? and shopping_cart_store_id=? and product_id=? and version=?
12/22/2020 07:48:00 - TRACE [org.hibernate.type.descriptor.sql.BasicBinder]: binding parameter [1] as [BIGINT] - [null]
12/22/2020 07:48:00 - TRACE [org.hibernate.type.descriptor.sql.BasicBinder]: binding parameter [2] as [BIGINT] - [null]
12/22/2020 07:48:00 - TRACE [org.hibernate.type.descriptor.sql.BasicBinder]: binding parameter [3] as [BIGINT] - [7]
12/22/2020 07:48:00 - TRACE [org.hibernate.type.descriptor.sql.BasicBinder]: binding parameter [4] as [BIGINT] - [1]
请注意,shopping_cart_user_id 和shopping_cart_store_id 的绑定参数为空。我不知道这是否是我的问题的原因,但似乎很可疑。当我调试代码时,被删除的 carItem 确实引用了 parentShopping 购物车,并且任何对象上的 id 都不为空,所以我不知道这些空值来自哪里。
有什么想法吗?
解决方法
您是否尝试将 Hibernate 更新到最新版本?如果是这样,并且您仍然遇到问题,请在问题跟踪器 (https://hibernate.atlassian.net) 中创建一个问题,并使用重现问题的测试用例 (https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java)。
,我在删除与此类似的 1:M 关系时遇到了巨大的问题。我做了各种各样的 removeFrom
和 delete
,最后都变成了一个大空头。
解决方案是使用 @Transactional
(来自 grails.gorm.transactions.Transactional
)显式注释服务方法。它神奇地让一切都像宣传的那样工作,级联等等。
服务类使用 @Service
进行注释。我错误地认为它暗示了 @Transactional
,因为默认情况下服务是事务性的,但这并不那么简单。此外,在没有对服务方法进行显式 @Transactional
注释的情况下,创建这些结构(几个 1:M 关系)也能正常工作。 IE。没有save()
问题,只有delete()
。