I’ve already searched about this, but still cannot figure out what I’m doing wrong. After calling save() the domain object id is null.
I’ve read it’ll happen if there’s a problem when saving the object, and that save(flush:true) should throw an error if that’s the case, but it’s not. Look at my code and the output:
def pic = new Picture(title:'XX', path:"XXX")
album.addToPictures(pic).save()
if(pic.validate())
println "no errors. New id: " + pic.id
else
println "with errors"
Output:
no errors. New id: null
And when using flush:true
def pic = new Picture(title:'XX', path:"XXX")
album.addToPictures(pic).save(flush:true)
if(pic.validate())
println "no errors. New id: " + pic.id
else
println "with errors"
Output:
no errors. New id: 17
As you can see, there aren’t any errors creating the object, and I should be able to get the id of the object after just calling save(). Any ideas?
Thanks
You are misunderstanding the timing of when an object actually gets persisted to the database. An object does not get persisted when you call
obj.save(), it gets persisted when whichever of the following happens first:A transaction can be started explicitly with
Normally, a transaction is also implicitly started for each call to a service method
If you don’t explicitly or implicitly use transactions, saved objects get persisted when the Hibernate session closes, which is (roughly) when the HTTP request completes.
However, if you call
someObject.save(flush: true)you are telling Hibernate to persist the object immediately, which is whyassigns an ID to the
Pictureinstance, butwill only assign the ID when the enclosing session/transaction is closed/committed
Update
Futher to your comment
Yes, use an explicit transaction, and save the file once you’re sure the object has been successfully persisted, roll the transaction back if persistence fails
Update 2
Further to your comment
You already know that
will provide you with the ID of the
Pictureinstance, so if you do this within a transaction you can get the ID without actually committing the transaction. However, I think this will only work if you’re using a database that uses sequences (Oracle, Postgres). Something like the following should work