I'm using the JPA EntityManager to do some operations, and one such operation is replacing an entity with another entity that has the same @Id
. So, given an oldObject
and a newObject
, what's the best way to remove the oldObject
and replace it with the newObject
?
Here's some code that doesn't work:
try
{
entityManager.getTransaction().begin();
entityManager.remove(oldObject);
entityManager.persist(newObject);
entityManager.getTransaction().commit();
}
catch (PersistenceException persistExc)
{
entityManager.getTransaction().rollback();
// do some stuff
}
This code gets the following exception:
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.depressio.SomeObject
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678)
Now, of course it works OK if instead of removing the entity, I just update its fields that have changed. However, I'm just being given the new object (the UI is tossing it at me via REST), so I really don't have any clue what fields have changed, so I'd have to update every field. If there's a ton of fields, that's not ideal.
I think I'm a little confused as to how to actually do a delete properly. I thought EntityManager.remove
was the right way, but I guess not.
Thanks in advance!
Edit 1: I feel I should note that oldObject.id == newObject.id. The id
is generated through a @SequenceGenerator
. Am I allowed to persist objects with identifiers if their identifier is annotated with a generator already?
Edit 2: According to the top upvoted answer here, because the @Id
is already defined and it's an auto-generated field, Hibernate is deeming it detached. Now I know why I get the exception, but the solution is still unclear.
That's what EntityManager.merge()
does. Pass it the new, detached entity, and it will merge its state to the old, attached entity. The detached entity will stay detached, and the old one will stay attached, but have its state replaced by the state of the new, detached one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With