web-dev-qa-db-fra.com

Est-il possible de détacher l'entité Hibernate, de sorte que les modifications apportées à l'objet ne soient pas automatiquement enregistrées dans la base de données?

J'ai une entité Hibernate que je dois convertir en JSON et je dois traduire certaines valeurs d'entité, mais lorsque je traduis des valeurs, ces valeurs sont instantanément enregistrées dans la base de données, mais je ne souhaite pas enregistrer ces modifications dans la base de données. Existe-t-il une solution de contournement pour ce problème?

47
newbie

Vous pouvez détacher une entité en appelant Session.evict() .

Vous pouvez également créer une copie défensive de votre entité avant la conversion des valeurs ou utiliser un DTO au lieu de l'entité dans ce code. Je pense que ces options sont plus élégantes car elles ne couplent pas la conversion en JSON et la couche de persistance.

41
axtavt

Vous pouvez également éviter que vos entités soient attachées à la session Hibernate en utilisant un StatelessSession:

StatelessSession session = sessionFactory.openStatelessSession();

au lieu de

Session session = sessionFactory.getCurrentSession();

Notez que vous devez prendre soin de fermer la StatelessSession, contrairement à la session Hibernate normale:

session.close(); // do this after you are done with the session

Une autre différence par rapport à la session normale est qu’une StatelessSession ne peut pas récupérer de collections. Je vois que c’est l’objet principal des opérations SQLQuery d’extraction de données uniquement.

Vous pouvez en savoir plus sur les différents types de session ici:

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

3
yglodt

Je suis également en train de convertir des entités de veille prolongée en JSON. 

La mauvaise chose lorsque vous fermez la session, vous ne pouvez pas charger des objets paresseux. Pour cette raison, vous pouvez utiliser

hSession.setDefaultReadOnly(true);

et fermez la session après lorsque vous avez terminé avec le JSON.

3
elkarel
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 le pojo de session
seconde: modifier les champs
alors: fais ce que tu veux faire

0
helloworld1970

Fermez la session. Cela détachera votre entité pour vous et aucune modification ne sera annulée. Si ce n'est pas possible, envisagez de désactiver autoFlush ... mais c'est une toute autre boîte de Pandore Le plus simple est de fermer la session et d’en finir!

0
stevevls