Quantcast

findOrSaveWhere .... duplicate key exceptions...????

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

findOrSaveWhere .... duplicate key exceptions...????

Chris Erickson
Hi,
I'm getting a duplicate key exception when trying to use findOrSaveWhere on a domain class. I don't know how this is possible when I'm handing in the entire key as part of the findOrSave.

Below is the domain class. The method is failing in the findOrSaveAll method at the bottom with an exception:

ERROR: hibernate.util.JDBCExceptionReporter Batch entry 0 insert into schema.object_reference (version, key, source, type, id) values ('0', '243', 'none', 'Feature', '379') was aborted.  Call getNextException to see the cause.
ERROR: hibernate.util.JDBCExceptionReporter ERROR: duplicate key value violates unique constraint "object_reference_type_source_key_key"

class ObjectReference {

    static constraints = {
        source(nullable: false, blank: false)
        type(nullable: false, blank: false)
        key(unique: ['source', 'type'], nullable: false, blank: false)
    }

    static beforeUpdate = {
        throw new InvalidOperationException("Object references cannot be updated.")
    }

    String source
    String type
    String key

    static String SOURCE_DEFAULT = "none"

    ObjectReference() {
        source = SOURCE_DEFAULT
    }
    /*
        Finds or creates all objects in the list.
        Objects should have the following properties:
        [source], type, key

        This method finds or creates all of the objects in the list.
     */
    static List<ObjectReference> findOrSaveAll(ArrayList objects) {
        def result = []
        for (int i = 0; i < objects.size(); i++) {
            def o = objects[i];
            o.source = o.source ?: SOURCE_DEFAULT
            if (o.source && o.type && o.key) {
                result << ObjectReference.findOrSaveWhere(source: o.source.toString().trim(), type: o.type.toString().trim(), key: o.key.toString().trim())
            }
        }
        return result
    }
}

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: findOrSaveWhere .... duplicate key exceptions...????

Jeff Brown-3

On Jul 18, 2012, at 2:51 PM, Chris Erickson wrote:

Hi,
I'm getting a duplicate key exception when trying to use findOrSaveWhere on a domain class. I don't know how this is possible when I'm handing in the entire key as part of the findOrSave.

Below is the domain class. The method is failing in the findOrSaveAll method at the bottom with an exception:

ERROR: hibernate.util.JDBCExceptionReporter Batch entry 0 insert into schema.object_reference (version, key, source, type, id) values ('0', '243', 'none', 'Feature', '379') was aborted.  Call getNextException to see the cause.
ERROR: hibernate.util.JDBCExceptionReporter ERROR: duplicate key value violates unique constraint "object_reference_type_source_key_key"

class ObjectReference {

    static constraints = {
        source(nullable: false, blank: false)
        type(nullable: false, blank: false)
        key(unique: ['source', 'type'], nullable: false, blank: false)
    }

    static beforeUpdate = {
        throw new InvalidOperationException("Object references cannot be updated.")
    }

    String source
    String type
    String key

    static String SOURCE_DEFAULT = "none"

    ObjectReference() {
        source = SOURCE_DEFAULT
    }
    /*
        Finds or creates all objects in the list.
        Objects should have the following properties:
        [source], type, key

        This method finds or creates all of the objects in the list.
     */
    static List<ObjectReference> findOrSaveAll(ArrayList objects) {
        def result = []
        for (int i = 0; i < objects.size(); i++) {
            def o = objects[i];
            o.source = o.source ?: SOURCE_DEFAULT
            if (o.source && o.type && o.key) {
                result << ObjectReference.findOrSaveWhere(source: o.source.toString().trim(), type: o.type.toString().trim(), key: o.key.toString().trim())
            }
        }
        return result
    }
}



It looks like you would get a duplicate if a record with o.source and o.type was already in the database but had a different o.key.  Is that correct?



jb
--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: findOrSaveWhere .... duplicate key exceptions...????

Chris Erickson
Yeah, I've worked around it with this, which WORKS, strangely enough.

The findOrCreate doesn't find it and tries to create it. Catching the exception and doing a find ends up finding the original....

Seems that something is out of sync / not cached correctly.

static List<ObjectReference> findOrSaveAll(ArrayList objects) {
        def result = []
        for (int i = 0; i < objects.size(); i++) {
            def o = objects[i];
            o.source = o.source ?: SOURCE_DEFAULT
            if (o.source && o.type && o.key) {
                // This should, but doesn't work consistently
                //result << ObjectReference.findOrSaveWhere(source: o.source.toString().trim(), type: o.type.toString().trim(), key: o.key.toString().trim())

                //HACK
                def map = [source: o.source.toString().trim(), type: o.type.toString().trim(), key: o.key.toString().trim()]
                def objectReference = ObjectReference.findWhere(map)
                if (!objectReference) {
                    objectReference = new ObjectReference(map)
                    try {
                        objectReference.save()

                    // sometimes this fails with a duplicate key exception, in that case, lets hack at this
                    // and just try getting it again.
                    // Chris: this makes me feel dirty, but it works...
                    } catch (Exception){
                        objectReference = ObjectReference.findWhere(map)
                        assert objectReference
                    }
                }
                result << objectReference
            }
        }
        return result
    }


On Wed, Jul 18, 2012 at 2:39 PM, Jeff Brown <[hidden email]> wrote:

On Jul 18, 2012, at 2:51 PM, Chris Erickson wrote:

Hi,
I'm getting a duplicate key exception when trying to use findOrSaveWhere on a domain class. I don't know how this is possible when I'm handing in the entire key as part of the findOrSave.

Below is the domain class. The method is failing in the findOrSaveAll method at the bottom with an exception:

ERROR: hibernate.util.JDBCExceptionReporter Batch entry 0 insert into schema.object_reference (version, key, source, type, id) values ('0', '243', 'none', 'Feature', '379') was aborted.  Call getNextException to see the cause.
ERROR: hibernate.util.JDBCExceptionReporter ERROR: duplicate key value violates unique constraint "object_reference_type_source_key_key"

class ObjectReference {

    static constraints = {
        source(nullable: false, blank: false)
        type(nullable: false, blank: false)
        key(unique: ['source', 'type'], nullable: false, blank: false)
    }

    static beforeUpdate = {
        throw new InvalidOperationException("Object references cannot be updated.")
    }

    String source
    String type
    String key

    static String SOURCE_DEFAULT = "none"

    ObjectReference() {
        source = SOURCE_DEFAULT
    }
    /*
        Finds or creates all objects in the list.
        Objects should have the following properties:
        [source], type, key

        This method finds or creates all of the objects in the list.
     */
    static List<ObjectReference> findOrSaveAll(ArrayList objects) {
        def result = []
        for (int i = 0; i < objects.size(); i++) {
            def o = objects[i];
            o.source = o.source ?: SOURCE_DEFAULT
            if (o.source && o.type && o.key) {
                result << ObjectReference.findOrSaveWhere(source: o.source.toString().trim(), type: o.type.toString().trim(), key: o.key.toString().trim())
            }
        }
        return result
    }
}



It looks like you would get a duplicate if a record with o.source and o.type was already in the database but had a different o.key.  Is that correct?



jb
--
Jeff Brown
SpringSource
http://www.springsource.com/

Autism Strikes 1 in 166
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/


Loading...