Bonjour,
Je lève une exception de type "a different object with the same identifier value was already associated with the session: [com.natixis.model.Enregistrement#2]" lorsque je veux mettre plusieurs fois le même objet dans une liste.
Contexte :
J'ai 3 classes principales :
Composant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 public abstract class Composant { protected java.lang.Integer id; protected String nom; protected String description; protected String description_defaut; protected Set<Conteneur> conteneurs; }Conteneur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 <hibernate-mapping> <class name="com.natixis.model.Composant" table="Composant" abstract="true"> <id name="id" type="int"> <column name="ID" /> <generator class="increment" /> </id> <property name="nom" type="java.lang.String"> <column name="NOM" /> </property> <property name="description" type="java.lang.String"> <column name="DESCRIPTION" /> </property> <property name="description_defaut" type="java.lang.String"> <column name="DESCRIPTION_DEFAUT" /> </property> <set name="conteneurs" table="ConteneurComposant" inverse="true"> <key column="composantId" not-null="true" /> <many-to-many column="conteneurId" class="com.natixis.model.Conteneur" /> </set> </class> </hibernate-mapping>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public abstract class Conteneur extends Composant { protected List<ConteneurComposant> listeComposants; }ComposantConteneur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 <hibernate-mapping> <joined-subclass name="com.natixis.model.Conteneur" extends="com.natixis.model.Composant" abstract="true"> <key column="ID" /> <list name="listeComposants" table="ConteneurComposant" lazy="false" cascade="all-delete-orphan"> <key column="conteneurId" not-null="true" /> <list-index column="ORDRE" /> <one-to-many class="com.natixis.model.ConteneurComposant" /> </list> </joined-subclass> </hibernate-mapping>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public class ConteneurComposant { private int id; private int multiplicite; private Composant composant; }La classe Enregistrement est une classe fille de Conteneur (et donc de composant).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 <hibernate-mapping> <class name="com.natixis.model.ConteneurComposant" table="ConteneurComposant"> <id name="id" type="int"> <column name="ID" /> <generator class="increment" /> </id> <property name="multiplicite" type="integer"> <column name="multiplicite" /> </property> <many-to-one name="composant" class="com.natixis.model.Composant" lazy="false" cascade="all"> <column name="composantId"></column> </many-to-one> </class> </hibernate-mapping>
Objectif :
Mon objectif est de pouvoir ajouter plusieurs fois un composant identique avec une multiplicité différente dans un conteneur.
Pour cela, je passe par une classe intermédiaire (ConteneurComposant).
Cas Test :
- Création d'un conteneur1
- Création d'un composant1
- Ajout du composant1 au conteneur1 (via un ConteneurComposant)
- Sauvegarde du conteneur1 (et des autres Objets par cascade)
- Listing des composants existant
- Ajout du composant1 (via un nouveau ConteneurComposant)
- Sauvegarde du conteneur, ce qui provoque une remontée d'erreur
Pour sauvegarder le conteneur j'utilise la méthode suivante :
Pour lister les composants ciblés j'utilise la méthode suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public class ConteneurDAO extends ComposantDAO { protected static void saveConteneur(Conteneur conteneur) { Global.logger.info("Sauvegarde du Conteneur " + conteneur.getNom()); Session session = sessionFactory.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.saveOrUpdate(conteneur); session.flush(); tx.commit(); } catch (HibernateException e) { if (tx != null) { tx.rollback(); } throw e; } finally { session.close(); } }
Je pense qu'il faut trouver un moyen pour utiliser la même instance des composants déjà chargés à chaque fois que je réalise une liste, mais j'ignore comment faire ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 @SuppressWarnings("unchecked") public static List<Conteneur> listeConteneur() { Global.logger .debug("Récupère la liste des flux et des enregistrements."); List<Conteneur> list = null; Session session = sessionFactory.openSession(); session.buildLockRequest(LockOptions.READ); list = (List<Conteneur>) session.createQuery("from Conteneur").list(); session.close(); Global.logger.debug("Récupération de " + list.size() + " Conteneur"); return list; }
Merci de l'aide que vous pourrez m'apporter
Partager