我遇到了这个奇怪的错误,无法在此问题的以前的答案中找到任何解决方案,我认为这与我的案件有关。

我在这样的域的afterInsert()方法中遇到此问题

Class Employee {
    /** other code **/

    def afterInsert() {
        println "Inserting..."
        if (!hasAfterInsert) {
            hasAfterInsert = true
            DatabaseEvent.withTransaction { status ->
                def dbEvent = new DatabaseEvent(loggedInUser: null,
                        type: "Created", entityClass: this.getClass().getName(), eventObjectId: this.id)
                dbEvent.save(failOnError: true)
            }
        }
    }
}

插入新员工后,我正在使用此方法创建记录,但是当我在afterInsert()中具有此代码时,就会抛出此错误。

我的DatabaseEvent类就像
class DatabaseEvent {

    ObjectId id
    String type
    String entityClass
    String eventObjectId
    Date dateCreated
    User loggedInUser
}

这给出了类似的东西:
E11000 duplicate key error index: myApp.Employee.$_id_ dup key: { : ObjectId('5631313fe4b0bbeba418859b') }

我不明白为什么在DatabaseEvent中保存afterInsert()对象时会发生这种情况?

最佳答案

因此,当您保存新的Employee实例时,尚未刷新GORM session ,这意味着您的新Employee实例仍在GORM session 中,并且新的Employee实例获得了新的idObjectId('5631313fe4b0bbeba418859b')

现在,在afterInsert()方法中,您正在使用同一事务来保存DatabaseEvent的新实例。在保存新的DatabaseEvent实例时,GORM再次刷新相同的GORM session ,并且再次尝试使用最近创建的Employee实例使用值id的相同ObjectId('5631313fe4b0bbeba418859b')保存,这会导致重复键错误。

因此,只需将afterInsert()方法中的代码更改为使用withNewSession而不是withTransaction闭包即可,这应该可以工作。

08-07 14:45