0

I have below code in my service class. This code is called twice from 2 different methods as part of a functionality.

        //Some code here... 
        LOG.info("###Inside customer interceptor");
        try
        {
            customerDao.save(customer);

        }
        catch (final Exception exp)
        {
        //some code here too...
        }

When it is first time called from first method and executed, I can see that there is a select SQL statement printed in tomcat console, but there is no update SQL statement as I expected(May be because of the fact that Hibernate doesn't issue an insert/update immediately). Immediately When this code block is called again from second method, I see a SQL select statement and then a SQL update statement in tomcat console, and immediately after that I see a big fat org.hibernate.NonUniqueObjectException. which as I can understand coming because the earlier entity was still attached to session and not committed to DB.

However when I go and see the database I find the values saved in the database were of the object from first call and not the second one as I expected. Is this normal or am I missing something here?

I am using Spring's annotation(@Transactional) driven transaction strategy.

Nirmal Mangal
  • 812
  • 1
  • 12
  • 26
  • Possible duplicate of [Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session](https://stackoverflow.com/questions/1074081/hibernate-error-org-hibernate-nonuniqueobjectexception-a-different-object-with) – Vadzim May 16 '19 at 19:26

1 Answers1

2

I'd rather use .merge(customer) method or .saveOrUpdate(customer) method to perform this operation.

  • If you use .merge, you will not get the nonUnique exception as it overwrites the object that is in the session with the one you just passed.
  • Where as to perform saveOrUpdate, the session should not have the same instance of the object you are trying to update or else you get this nonUniqueObject exception.

Because you are using spring @Transactional, the transaction should be committed after the complete method has been executed.

Zeus
  • 6,386
  • 6
  • 54
  • 89
  • Thanks Zeus. Yes, for testing purpose I tried using merge() as other posts suggested and it does save the new object instead of the obsolete one and I do not get nonUniqueObject exception. However my questions was more to understand why in spite of using @Transactional at the method level why it did not commit after the end of execution of the method and secondly why obsolete object is saved in data store on calling the save method instead of the current. – Nirmal Mangal Mar 12 '14 at 18:27
  • I may need to understand how the calls are made to answer your question. If same session is used to update two customer objects of same ID, then you get that exception non unique exception. Somewhere in your code, the session is not closing, so first time you save, no error, and second time it gives error as the session already has that object. Also, save is used to store the transient objects rather than detached objects. – Zeus Mar 12 '14 at 18:35
  • Well...I am using this code inside Hybris eCommerce platform, and This code is inside an Interceptor class which is triggered whenever there is any change in the model related to this interceptor. ALso I am using googlecode implementation of hibernate where save() exactly does what saveOrUpdate() will do in other Hibernate implementations. – Nirmal Mangal Mar 12 '14 at 18:51
  • I dont know if the spring @Transactional is used to close the session for the google version of the hibernate, spring does not automatically provide support for all, you may have to check ths link to kno the supported ORM tools here http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/transaction.html – Zeus Mar 12 '14 at 18:57