1

I have a managedbean that has a list of entity objects of current page. after I create a new object and persist it to db using persist() in a transaction; in another transaction when I call merge(because the entity is in detached state due to previous transaction commit); entitymanager cannot find the object in persistence context and throw a select query to database. Am I missing something or is that normal behavior?

Update: The above problem exists when I use mysql database and autogenerated Id column. It does not exist when I use Oracle where I use sequence for Ids; but still; persistence context should know about the generated id; also is there any way to peek into persistence context to see what entities exits; I am using hibernate btw

x0r
  • 45
  • 2
  • 10

2 Answers2

1

It is normal behevior. A persistence context, by default, has the same lifetime of the transaction. And it's completely normal: once the transaction is committed, other transactions might modify the entity, and Hibernate must reload the entity from the database to make sure it doesn't return stale values.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • But I call merge; why cant it just merge without querying the database? – x0r Nov 02 '12 at 10:09
  • Because merge means just that: copy the state of the passed detached entity to the attached entity retrieved from the database. Since you're in another transaction, the cache is empty, and it needs to load the entity from the database. – JB Nizet Nov 02 '12 at 14:58
  • I am sorry I am new to this environment -Hibernate JPA- so I dont have a solid knowledge as you see; but, same architecture works one Oracle without the extra select statement. I think it has something to do with the auto-generated id; but I dont know why. I am on it. – x0r Nov 02 '12 at 15:37
  • In your Oracle environment, either the entity is already loaded in the session ast the time you merge it, or you have a second level cache which contains the entity. It has nothing to do with auto-generated IDs (if the scenario you describe is the reality: you should add code to your question, as well as the extra query that you're seeing). – JB Nizet Nov 02 '12 at 15:40
  • I forgot I setup second-level cache; I use ehcache - I resolved one of my issues - when I read entity from database it doesnt need extra select on merge (since it is in cache); but when I try to merge newly inserted entity; it requires. But; I still have one problem; I use same codebase for Oracle and MySql and Oracle does not require the extra select; do you have any clues for that? – x0r Nov 02 '12 at 19:42
  • As I said, you should add code to your question, as well as the extra query that you're seeing. – JB Nizet Nov 02 '12 at 19:43
1

This is normal behaviour.. if the instance is not in the persistence context, it needs to know if it exists or not (should be overwritten or newly created later).

ID generation: the generated ID is usually returned on call to persist(..), which is quite handy, so your application can use the newly created ID right away, no need to wait for the end of the transaction.

You can check if a given object is in the persistence context by calling: https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Session.html#contains%28java.lang.Object%29

Istvan Devai
  • 3,962
  • 23
  • 21
  • I dont understand how it is relevant; when I persist; it should add to persistenceContext and I should merge without select query; am I wrong? – x0r Nov 02 '12 at 10:17