Grails / GORM : org.hibernate.AssertionFailure: null id in xyz (发生异常后不刷新会话)

Grails / GORM : org.hibernate.AssertionFailure: null id in xyz (don't flush the Session after an exception occurs)

编辑: 得到了 -1,您能解释一下原因吗?我搜索了重复项,但没有找到。

针对我刚刚遇到的问题发布 Q/A:

class Pineapple {
    def pineappleService

    Supplier supplier;

    def beforeInsert() {
        pineappleService.beforeInsert(this);
    }
}

class PineappleService {
    def beforeInsert(Pineapple pineapple) {
         Pineapple.withNewSession {
             // some logic
             pineapple.supplier.save();
         }
    }
}

异常:

org.hibernate.AssertionFailure: null id in xyz (don't flush the Session after an exception occurs)

诀窍是将闭包移动到域 class:

class Pineapple {
    def pineappleService

    Supplier supplier;

    def beforeInsert() {
        Pineapple.withNewSession {
            pineappleService.beforeInsert(this);
        }
    }
}

class PineappleService {
    def beforeInsert(Pineapple pineapple) {
         // some logic
         pineapple.supplier.save();
    }
}

文档:

Notice the usage of withNewSession method above. Since events are triggered whilst Hibernate is flushing using persistence methods like save() and delete() won't result in objects being saved unless you run your operations with a new Session.

Fortunately the withNewSession method lets you share the same transactional JDBC connection even though you're using a different underlying Session.