简体   繁体   中英

GRAILS - GORM : DuplicateKeyException during saving a new object

I use GORM to back occurrences in a database, from an excel file.

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 .

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.

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"

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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