IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Instancier plusieurs fois un même objet persisté


Sujet :

Hibernate Java

  1. #1
    Membre à l'essai
    Inscrit en
    Octobre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 14
    Points : 15
    Points
    15
    Par défaut Instancier plusieurs fois un même objet persisté
    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;
    }
    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>
    Conteneur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public abstract class Conteneur extends Composant {
     
    	protected List<ConteneurComposant> listeComposants;
    }
    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>
    ComposantConteneur :
    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;
    }
    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>
    La classe Enregistrement est une classe fille de Conteneur (et donc de composant).

    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 :
    1. Création d'un conteneur1
    2. Création d'un composant1
    3. Ajout du composant1 au conteneur1 (via un ConteneurComposant)
    4. Sauvegarde du conteneur1 (et des autres Objets par cascade)
    5. Listing des composants existant
    6. Ajout du composant1 (via un nouveau ConteneurComposant)
    7. Sauvegarde du conteneur, ce qui provoque une remontée d'erreur


    Pour sauvegarder le conteneur 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();
    		}
    	}
    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
    	@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;
    	}
    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 ?

    Merci de l'aide que vous pourrez m'apporter

  2. #2
    Membre à l'essai
    Inscrit en
    Octobre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 14
    Points : 15
    Points
    15
    Par défaut
    J'ai peut être trouvé une solution. J'ai modifié ma fonction de sauvegarde pour recharger les éléments avant de les sauvegarder :

    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
    	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();
    			for (ConteneurComposant Ccomp : conteneur.getListeComposants()) {
    				Ccomp.setComposant((Composant) session.merge(Ccomp
    						.getComposant()));
    			}
    			session.saveOrUpdate(conteneur);
    			session.flush();
    			tx.commit();
    		} catch (HibernateException e) {
    			if (tx != null) {
    				tx.rollback();
    			}
    			throw e;
    		} finally {
    			session.close();
    		}
    	}
    Cette solution me parait un peu bancale, je laisse donc le post en non résolut si quelqu'un à mieux à me proposer, je suis preneur. Je vais voir dans mes prochains développements si cela de gêne pas les modifications de composant.

Discussions similaires

  1. Réponses: 17
    Dernier message: 19/09/2012, 16h52
  2. Réponses: 0
    Dernier message: 18/09/2012, 11h56
  3. Plusieurs fois le même objet dans un Canvas
    Par Invité dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 27/06/2011, 16h46
  4. Réponses: 7
    Dernier message: 21/09/2007, 15h26
  5. Instancier plusieurs fois le même écran?
    Par QAYS dans le forum Delphi
    Réponses: 10
    Dernier message: 04/04/2007, 13h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo