2

Let's say I would like to merge a detached entity. when I do

T mergedEntity = entityManager.merge(detachedEntity);

the entityManager will load an entity (with same identifier with the detachedEntity) from database and copy all the data from the detachedEntity to the new loaded entity. When later my transaction ends, this entity will be saved to the database.

However, in a concurrent scenario, the entity in the database can be updated by other transactions between the entity is firstly loaded in my transaction and then flushed at the end of my transaction. In this case, I would like to know whether an OptimisticLockException will be thrown? If so, why the merge API doesn't specify the OptimisticLockException in Java doc? http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge(T)

thanks

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
danny
  • 3,046
  • 3
  • 23
  • 28
  • I think merge won't retrieve the resulting managed entity from the database but will just clone the given detached instance. AFAIK it will anyway retrieve the version value at this time when optimistic locking is enable. I'd like @JB Nizet to confirm if he doesn't mind. – Gab Apr 06 '14 at 19:52

2 Answers2

4

Because the merge() method is not what will throw this exception. This exception will be thrown when the state of the entity, in memory, will be flushed to the database. That doesn't happen when merge() is called, when flush() is called, either explicitely, or before the commit, or before a query is executed.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • thanks for reminding that merge doesn't flush database. that should happen at the end of the transaction – danny Apr 07 '14 at 03:15
3

Will JPA EntityManager's merge method lead to OptimisticLockException?

No, not directly.

I would like to know whether an OptimisticLockException will be thrown? If so, why the merge API doesn't specify the OptimisticLockException in Java doc?

An OptimisticLockException can obviously only be thrown if you configured optimistic locking at all. Furthermore, since it inherits from java.lang.RuntimeException the merge method wouldn't have to declare it anyway.

BUT this is all hypothetical because OptimisticLockException isn't even thrown during the merge phase but while flushing changes to the datasource.

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
  • OptimisticLockException inheriting RuntimeException may not be the reason that it is not declared in the method because the EntityManager find and lock method do declare OptimisticLockException. I think the reason is as you and other said, merge doesn't cause the problem directly. thanks the same! – danny Apr 07 '14 at 03:21