GRAILS - GORM:保存新对象期间出现 DuplicateKeyException

GRAILS - GORM : DuplicateKeyException during saving a new object

我使用 GORM 从 excel 文件中备份数据库中的事件。

new ExcelBuilder(excelFile.inputStream).eachLine([labels: true, sheet: 0]) {
                if (cell(0)) {
                    def nameA = cell(0)
                    def nameB = cell(1)
                    def a = Chapitre.findByNom(nameA)

                def code = cell(2)
                def designation = cell(3)

                if (code == null || nameA == null || nameB == null) {
                    flash.messages << "error"
                } else if (!Chapitre.findByNom(nameA)) {
                    flash.messages << "error"
                } else if ( Rubrique.where{nom == nameB && chapitre == a}.list().size() == 0) {
                    flash.messages << "error"
                } else if(Object.where{rubrique == Rubrique.findByNom(nameB) && c == code && d == designation}.count() > 0){
                    flash.messages << "error"
                } else {

                        def b = Rubrique.findByNom(nameB)
                        def isNew = false;

                        Object.withNewSession {session2->
                            def object = Object.findOrCreateByCode(code)

                            if(object.designation == null)
                                isNew = true;

                            object.rubrique = b
                            object.d= (designation == null)?"":designation
//                              try {
                                    rowCount += object.save()? 1 : 0
//                              } catch(ValidationException) {
//                                    if(isNew)
//                                        rowCount++;
//                                    log.info("ErreuRRRRRRRRrrrRRrrRrRRrrrrRrrrRrrrRrrrr")
//                              }
                            }
                    }
                }
                currentLine++
}
flash.messages << "${rowCount} ligne create or update"

一更新打消后顾之忧,文件行进程继续,数据库记录有效。

然而,在插入新对象时,出现异常:

org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session:[fen.NuisanceType#2202]; 
nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

有问题的对象注册有效,但是文件路径错误。

当我取消注释 trycatch 时,我绕过了错误,因此每个文件的所有副本都在数据库中创建。

因此我找到了解决我的担忧的方法,但我觉得它不是很干净,所以我来找你试图理解我的问题。

没有进一步的信息,很难给出明确的答案。这段代码回到服务中了吗?(非常怀疑它,因为它有 flash.message 指向控制器执行所有这些。)尝试将其变成服务和事务,然后也许您可以考虑删除 withNewTransaction 调用。

您可以在此处阅读有关创建错误的更多信息: Grails - DuplicateKeyException 点评评论: "Well, that problem occurs when you are initializing a class new ClassD with an id or unique property manually, when there is another already in the session. So, you should try to get that entity first (that's what findOrCreateWhere does, but if you use an id you need to use get) and then use the instance found or create a new one for the update"

Hibernate Error: a different object with the same identifier value was already associated with the session

您整理了代码并从服务中 运行:(问题可能会消失)因为我还清理了您正在做的重复发现:

class TestService {

    static transactional=true

    def saveRecord()  {
        def results=[]
        new ExcelBuilder(excelFile.inputStream).eachLine([labels: true, sheet: 0]) {
            if (cell(0)) {
                def nameA = cell(0)
                def nameB = cell(1)
                def code = cell(2)
                def designation = cell(3)

                def a = Chapitre.findByNom(nameA)
                def b = Rubrique.where{nom == nameB && chapitre == a}
                def c = Object.where{rubrique == b && c == code && d == designation}

                if (!code||!nameA||!nameB||!a||!b||!c) {
                    results << "Error saving ${nameA} ${nameB} ${code}"
                } else {
                    //boolean isNew = false
                    def object = Object.findOrSaveWhere(code:code)
                    if(object) { 
                        if (!object.designation) {
                            rowCount++
                            results << "Record ${object} has no designation ? new Record?"
                        }
                        object.rubrique = b
                        object.d = designation ?: ''
                        object.save()
                        results << "Record ${object.id} is saved"
                    } else {
                        /*
                         *  Could not save or find code:code now create a new object:
                         *  object = new Object(code:code, rubrique:rubrique: d: designation ?: '').save()
                         *  
                         */
                    }   
                }
            }
            currentLine++
        }
        results <<  "${rowCount} ligne create or update"
        return results
    }
}