I spent entire evening try to figure it out and I am desperate at this point.
I have service class in my Grails 2.1.0 project. It performs queries against web-service - queries are threaded. Once thread got the data it calls synchronized
method WriteToDB
, which in turn takes a name (String field
) and checks against domain via findByName
. If a record exists then do nothing else create a new record.
Now I checked and method indeed allows only one thread at the time to be called, here is log sample:
Error 2013-01-02 21:29:47,408 [Thread-21] ERROR - WriteToDB START
Error 2013-01-02 21:29:47,474 [Thread-21] ERROR - WriteToDB
FINISHED
Error 2013-01-02 21:29:47,475 [Thread-20] ERROR - WriteToDB START
Error 2013-01-02 21:29:47,571 [Thread-20] ERROR - WriteToDB
FINISHED
Error 2013-01-02 21:29:47,581 [Thread-49] ERROR - WriteToDB START
Error 2013-01-02 21:29:47,866 [Thread-49] ERROR - WriteToDB
FINISHED
Error 2013-01-02 21:29:47,867 [Thread-45] ERROR - WriteToDB START
Error 2013-01-02 21:29:48,202 [Thread-45] ERROR - WriteToDB
FINISHED
Error 2013-01-02 21:29:48,203 [Thread-48] ERROR - WriteToDB START
Error 2013-01-02 21:29:48,320 [Thread-48] ERROR - WriteToDB
FINISHED
However, I get duplicated records!!! Every time I save new record I do flush:true
on it. I don't understand why is it keep happening? I tested manually - added one known record to DB prior to the test and it never got duplicated, however, new ones that are being saved get to be duplicated up-to 6 times.
Please help. Do I need to index something? Or flush something in a special way? Why is it happening?
[Update 2/1/2013]:
Here is a code that I am using to save the record:
if(!f) { // Check if record doesn't exist then save, else nothing
f = new Feature(name: featureName)
if( !f.save(flush: true) ) {
f.errors.each {
log.error it
}
}
}
Also Error sample:
Error 2013-01-02 22:25:58,868 [Thread-20] ERROR
util.JDBCExceptionReporter - Duplicate entry 'Automatic transmission'
for key 'name'
Error 2013-01-02 22:25:58,873 [Thread-20] ERROR
hibernate.AssertionFailure - an assertion failure occured (this may
indicate a bug in Hibernate, but is more likely due to unsafe use of
the session) Message: null id in Project2.Feature entry (don't flush
the Session after an exception occurs)
I can interpret this way (I got FindByName before 'save' part of the code):
I lookup record and it doesn't exist so I am creating it, now it complains about Duplicate entry and I am getting null for variable 'f' which I later insert into another table as a relation.
I think I might try to fix this code with try catch block... ideas?