EntityManager there are the
persist() methods. In hibernate there’s more –
saveOrUpdate, update, merge. I’m always using
merge() for the sake of simplicity, but one must be aware what is the exact behaviour of this method.
I had to read the JPA spec (1.0, but I guess it should be unchanged in 2.0) in order to get the following:
- if the entity is already in the persistence context (session), no action is taken, except for cascades
- if the entity is detached, a copy (object’) is returned, which is attached (managed)
- if the entity is transient (new instance), it is saved and a persistent (and managed) copy is returned
- if the entity is detached, but an object with the same identifier exist in the current entity manager, then the state of the detached object is copied into the current persistent entity, and it (the current) is returned
Here’s a test that depicts what’s happening:
Message msg = new Message(); msg.setText("Foo"); Message msg2 = em.merge(msg); System.out.println("New, transient object: " + msg); System.out.println("Merged object: " + msg2); Message msg3 = em.merge(msg2); System.out.println("Merging persistent object: " + msg3); Message msg4 = new Message(); msg4.setText("Bar"); msg4.setId(msg3.getId()); Message msg5 = em.merge(msg4); System.out.println("Detached entity with same id: " + msg5); System.out.println("Merged text: " + msg5.getText()); em.clear(); Message msg6 = em.merge(msg5); System.out.println("Merged detached entity: " + msg6);
And the resulet is:
New, transient object: com.foo.model.Message@1f Merged object: com.foo.model.Message@8da6fe83 Merging persistent object: com.foo.model.Message@8da6fe83 Detached entity with same id: com.foo.model.Message@8da6fe83 Merged text: Bar Hibernate: select message0_.id as id1_1_, message0_.authorId ..... Merged detached entity: com.foo.model.Message@a13fade8
I haven’t had problems with using
merge() only, but one must know what he’s getting.
(Note: The same goes for Hibernate’s