【问题标题】:Hibernate error deleting child record Grails 4休眠错误删除子记录Grails 4
【发布时间】:2020-12-22 12:55:06
【问题描述】:

我很难将孩子从协会中移除。我正在使用 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', 'bigint(20)', 'NO', 'PRI', '', ''
'product_id', 'bigint(20)', 'NO', 'PRI', '', ''
'version', 'bigint(20)', 'NO', '', '', ''
'date_created', 'datetime', 'NO', '', '', ''
'last_updated', 'datetime', 'NO', '', '', ''
'quantity', 'int(11)', 'NO', '', '', ''
'purchase_price', 'decimal(19,2)', 'NO', '', '', ''
'last_item_added', 'datetime', 'NO', '', '', ''

我正在尝试删除购物车项目。我已经读过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 的绑定参数为空。我不知道这是否导致了我的问题,但似乎很可疑。当我通过代码进行调试时,被删除的 cartItem 确实有对 parentShopping 购物车的引用,并且任何对象上的 id 都不是 null,所以我不知道这些 null 来自哪里。

有什么想法吗?

【问题讨论】:

    标签: hibernate grails grails-orm has-and-belongs-to-many


    【解决方案1】:

    您是否尝试将 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)。

    【讨论】:

    • 不,我没有尝试更新 Hibernate。老实说,我什至不确定如何在 Grails 中做到这一点。我目前在 Grails 4.0.3 上。当我查看 build.gradle 时,我看到对 hibernate5:7.0.0 和 hibernate-core:5.4.0.Final 的依赖。
    • 那就尝试更新到最新的5.4版本
    【解决方案2】:

    我只是在删除与此类似的 1:M 关系时遇到了巨大的问题。我做了各种各样的removeFromdelete 最终成为一个大空操作。

    解决方案是使用@Transactional(来自grails.gorm.transactions.Transactional)显式注释服务方法。它神奇地让一切都像宣传的那样工作,级联等等。

    服务类被注释为@Service。我错误地认为它暗示了@Transactional,因为默认情况下服务是事务性的,但这并不是那么简单。此外,在服务方法上没有明确的@Transactional 注释的情况下,创建这些结构(几个 1:M 关系)也能正常工作。 IE。没有save() 问题,只有delete()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      相关资源
      最近更新 更多