Is it possible to detach Hibernate entity, so that changes to object are not automatically saved to database?

JavaHibernatePersistence

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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.

Solution 3 - Java

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:

http://www.interviewadda.com/difference-between-getcurrentsession-opensession-and-openstatelesssession/

Solution 4 - Java

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!

Solution 5 - Java

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

Solution 6 - Java

In my case I just flushed and cleared the session.

session.flush(); session.clear();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnewbieView Question on Stackoverflow
Solution 1 - JavaaxtavtView Answer on Stackoverflow
Solution 2 - JavaelkarelView Answer on Stackoverflow
Solution 3 - JavayglodtView Answer on Stackoverflow
Solution 4 - JavastevevlsView Answer on Stackoverflow
Solution 5 - Javahelloworld1970View Answer on Stackoverflow
Solution 6 - JavaEliasView Answer on Stackoverflow