I have Hibernate entity that I have to convert to JSON, and I have to translate some values in entity, but when I translate values, these values are instantly saved to database, but I don't want to save these changes to database. Is there any workaround for this problem?
6 Answers
You can detach an entity by calling Session.evict().
Other options are create a defensive copy of your entity before translation of values, or use a DTO instead of the entity in that code. I think these options are more elegant since they don't couple conversion to JSON and persistence layer.
-
22In case of JPA, you can use: [`EntityManager.detach(object)`](http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#detach%28java.lang.Object%29) – Christian Müller Jan 13 '14 at 13:48
-
3I was always using DTO for this purpose. Using defensive copy is good idea but the maintenance becomes tougher as down the year, people think the new object is a managed one but in realy it is actualy a local copy. – VimalKumar Jul 29 '15 at 19:47
I am also converting hibernate entities to JSON.
The bad thing when you close the session you cannot lazy load objects. For this reason you can use
hSession.setDefaultReadOnly(true);
and close the session after when you're done with the JSON.
- 701
- 2
- 6
- 20
You can also avoid that your entities are attached to the Hibernate Session by using a StatelessSession:
StatelessSession session = sessionFactory.openStatelessSession();
instead of
Session session = sessionFactory.getCurrentSession();
Note that you must take care yourself of closing the StatelessSession, unlike the regular Hibernate Session:
session.close(); // do this after you are done with the session
Another difference compared to the regular Session is that a StatelessSession can not fetch collections. I see it's main purpose for data-fetching-only SQLQuery stuff.
You can read more about the different session types here:
- 12,552
- 14
- 82
- 121
public static <E> E deepClone(E e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo;
try {
oo = new ObjectOutputStream(bo);
oo.writeObject(e);
} catch (IOException ex) {
ex.printStackTrace();
}
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi;
try {
oi = new ObjectInputStream(bi);
return (E) (oi.readObject());
} catch (IOException ex) {
ex.printStackTrace();
return null;
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
return null;
}
}
first: deepClone the session pojo
second: alter fields
then: do whatever you want to do
- 61
- 3
Close the Session. That will detach your entity for you, and no modifications will be flushed. If that's not possible, look into disabling autoFlush...but that's a whole other can of worms. The easiest is to close the Session and be done with it!
- 10,535
- 1
- 44
- 50
In my case I just flushed and cleared the session.
session.flush(); session.clear();
- 574
- 8
- 22