简体   繁体   English

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

[英]GRAILS - GORM : DuplicateKeyException during saving a new object

I use GORM to back occurrences in a database, from an excel file. 我使用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"

An update will break any worries, the course of the lines of file continue and database recording is effective. 更新将消除任何后顾之忧,文件行的过程继续进行,数据库记录有效。

However when it comes to inserting a new object, I get an Exception: 但是,当涉及到插入新对象时,出现异常:

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

The registration of the object in question is effective , but the error raised off the path of the file. 有问题的对象的注册是有效的,但是该错误引起了文件路径的错误。

When i uncommented the try and catch I bypasses the error and so all my copies of each file are created in the database . 当我取消注释try and catch我绕过了错误,因此每个文件的所有副本都在数据库中创建。

I thus found a way around my worries, but I do not find it very clean and i come to you to try to understand my problem. 因此,我找到了解决问题的方法,但是我发现它并不是很干净,我来找您尝试理解我的问题。

Without further information hard to give any clear answers. 没有更多信息,很难给出任何明确的答案。 Is this code back in a service?(very much doubt it since it has flash.message pointing to controller doing all of it.) Try making it into a service and transactional then maybe you could look at removing withNewTransaction call. 这段代码是否还存在于服务中?(由于它具有flash.message指向控制器执行所有操作,因此非常怀疑。)尝试使其成为服务并进行事务处理,然后您可能会考虑使用withNewTransaction调用删除它。

You can read more about error created here: Grails - DuplicateKeyException Review comment: "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" 您可以在此处阅读有关创建的错误的更多信息: Grails-DuplicateKeyException评论评论:“好吧,当您在会话中已经有另一个具有ID或unique属性的类手动初始化新的ClassD时,会发生此问题。因此,您应该尝试先获取该实体(这是findOrCreateWhere所做的,但是如果您使用ID,则需要使用get),然后使用找到的实例或为更新创建一个新实例”

Hibernate Error: a different object with the same identifier value was already associated with the session 休眠错误:具有相同标识符值的另一个对象已与会话关联

You code tidied up and running from service: (issues may go away) since I have also cleaned up the duplicated finds you were doing: 您整理过的代码并从服务中运行:(问题可能会消失),因为我还清理了您正在执行的重复发现:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM