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?
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.
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:
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.
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
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!