Marco
Marco

Reputation: 15929

Do I need a double save() after a domain modification using afterInsert()?

I have a domain class that modifies one of its properties in the afterInsert event.

A small example:

class Transaction {
   Long transactionId

   static constraints = {
       transactionId nullable: true
   }

   def afterInsert() {
       // copy the record id to transactionId;
       transactionId = id
   }
}

Whenever I save the domain object (transaction.save(flush: true)) in my unit tests, all is well, and the transactionId is updated. But when I try to find the saved record using Transaction.findByTransactionId(), I get no results:

   // do something
   transaction.save(flush: true)
   Transaction transaction = Transaction.findByTransactionId(1)
   // !! no results; transaction == null

And I have to do a double save() before I can find the record using findByTransactionId():

   // do something
   transaction.save(flush: true)
   transaction.save(flush: true)
   Transaction transaction = Transaction.findByTransactionId(1)
   // !! it works....

The double save() seems awkward. Any suggestions on how to eliminate the need for it?

Upvotes: 1

Views: 1292

Answers (2)

Michael J. Lee
Michael J. Lee

Reputation: 12416

The call to save() will return the persisted entity if validation passes, so there isn’t any reason to look it up separately afterwards. I think that your problem is that you’re re-instantiating the transaction variable (using that same name). If you must look it up (I don’t suggest doing so), call it something else. Also, the 1 id that you’re looking up may not exist if the column is an AUTO-INCREMENT.

      def a = a.save(flush: true)
      a?.refresh() // for afterInsert()
      Transaction b = (a == null) ? null : Transaction.findByTransactionId(a.id)
      // (Why look it up? You already have it.)

Update:

Because you’re using afterInsert(), Hibernate may not realize that it needs to refresh the object. Try using the refresh() method after you call save().

Upvotes: 1

Marco
Marco

Reputation: 15929

This small piece of code makes it obviously work:

def afterInsert() {
    transactionId = id
    save() // we need to call save to persist the changens made to the object
}

So calling save in the afterInsert is needed to persist the changes made in afterInsert!

Upvotes: 0

Related Questions