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 :

Illegal attempt to associate a collection with two open sessions. Collection


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut Illegal attempt to associate a collection with two open sessions. Collection
    Bonjour, je me retrouve avec cette erreur dans mon projet java lorsque je veux supprimer un objet "Gisement". J'ai essayé de trouver d'où cela pouvait venir en cherchant sur internet mais sans succès.
    Cela pourrait venir d'un tableau mal déclaré, d'une mauvaise gestion des CASCADE ou encore des transactions.
    Je vais reprendre ce qui est, pour moi, important à montrer pour m'aider à résoudre ce problème.

    J'avais déjà eu ce souci dans un projet que j'avais abandonné en cours de route. Je pense que cela doit venir de la même chose.
    Hibernate valide sans problème ma base de données, le problème ne vient pas de là mais sans doute d'une ignorance de ma part dans mon code.

    Je suis le même fonctionnement pour un autre (aussi une suprresion) cas et je n'ai pas cette erreur.

    L'erreur se déclenche sur le "session.delete(obj)" de abstractDao et si on remonte, il englobe ce code :
    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
    23
    24
    25
    26
    27
    28
     
    public abstract class AbstractDao<T> {
        //protected static final Logger LOGGER = LogManager.getLogger(AbstractDao.class);
        protected Class<T> modelClass;
     
        private SessionFactory sf;
        private InitSessionFactory i = new InitSessionFactory();
     
        public void setmodelClass(Class<T> modelClass) {
            this.modelClass = modelClass;
     
            sf = i.getSessionFactory();
        }
     
        protected final Session getSession() {
            Session session = null;
            try {
                session = this.sf.getCurrentSession();
            } catch (Exception e) {
                //LOGGER.error(e);
            }
     
            if (session == null)
                session = sf.openSession();
     
            return session;
        }
        //session.delete(obj);
    Dans un première temps, le message d'erreur complet :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    Type Rapport d'exception
    message org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [Models.Gisement.listeEquipesGisement#5]
     
    description Le serveur a rencontré une erreur interne qui l'a empêché de satisfaire la requête.
     
    exception
     
    javax.persistence.PersistenceException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [Models.Gisement.listeEquipesGisement#5]
    	org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    	org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    	org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    	org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:914)
    	org.hibernate.internal.SessionImpl.delete(SessionImpl.java:836)
    	Dao.AbstractDao.delete(AbstractDao.java:70)
    	Controllers.AdminPersistServlet.doGet(AdminPersistServlet.java:239)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
     
    cause mère
     
    org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [Models.Gisement.listeEquipesGisement#5]
    	org.hibernate.collection.internal.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:693)
    	org.hibernate.event.internal.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:46)
    	org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
    	org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
    	org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
    	org.hibernate.event.internal.AbstractVisitor.process(AbstractVisitor.java:126)
    	org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:119)
    	org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:72)
    	org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)
    	org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:904)
    	org.hibernate.internal.SessionImpl.delete(SessionImpl.java:836)
    	Dao.AbstractDao.delete(AbstractDao.java:70)
    	Controllers.AdminPersistServlet.doGet(AdminPersistServlet.java:239)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
     
    note La trace complète de la cause mère de cette erreur est disponible dans les fichiers journaux de ce serveur.
    Maintenant, pour mes différentes classes, j'ai d'un côté le couple "Gisement" qui est la classe parente de "Mineraux" et "Gaz".
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @DiscriminatorColumn(name = "type_gisement", discriminatorType = DiscriminatorType.STRING)
    @Table(name="Gisement")
    public class Gisement {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
     
        /* https://stackoverflow.com/questions/32749531/psqlexception-the-column-index-is-out-of-range-7-number-of-columns-6-postg */
        // add @Column(insertable = false, updatable = false) annotation to the discriminator field
        @Column(name="type_gisement", nullable = false, insertable = false, updatable = false)
        protected String typeGisement;
        //@OneToMany(targetEntity=Equipe.class, mappedBy = "gisement", fetch = FetchType.LAZY)
        @OneToMany(mappedBy = "gisement")
        protected List<Equipe> listeEquipesGisement;
     
        @Column(name="date_mise_service")
        private LocalDate dateMiseEnService;
        @Column(name="rendement_mensuel")
        private int rendementMensuel;
     
     
        public Gisement() {
            //
        }
        public Gisement(LocalDate dateMiseEnService, int rendementMensuel) {
            this();
            this.dateMiseEnService = dateMiseEnService;
            this.rendementMensuel = rendementMensuel;
            this.listeEquipesGisement = new ArrayList<>();
        }
     
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
     
        public String getTypeGisement() {
            return typeGisement;
        }
        public void setTypeGisement(String typeGisement) {
            this.typeGisement = typeGisement;
        }
     
        public List<Equipe> getListeEquipesGisement() {
            return listeEquipesGisement;
        }
        public void setListeEquipesGisement(List<Equipe> listeEquipesGisement) {
            this.listeEquipesGisement = listeEquipesGisement;
        }
     
        public LocalDate getDateMiseEnService() {
            return dateMiseEnService;
        }
        public void setDateMiseEnService(LocalDate dateMiseEnService) {
            this.dateMiseEnService = dateMiseEnService;
        }
     
        public int getRendementMensuel() {
            return rendementMensuel;
        }
        public void setRendementMensuel(int rendementMensuel) {
            this.rendementMensuel = rendementMensuel;
        }
    }
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    import org.hibernate.annotations.OnDelete;
    import org.hibernate.annotations.OnDeleteAction;
    import javax.persistence.*;
    import java.time.LocalDate;
     
    @Entity
    @PrimaryKeyJoinColumn(name="id", foreignKey=@ForeignKey(name = "FK_Gaz_Guisement"))
    @DiscriminatorValue("gaz")
    @Table(name="Gaz")
    @OnDelete(action = OnDeleteAction.CASCADE)
    public class Gaz  extends Gisement {
        private double densite;
        @Column(name="type_gaz")
        private String typeGaz;
     
        public Gaz() {
            //
        }
        public Gaz(LocalDate dateMiseEnService, int rendementMensuel, double densite, String typeGaz) {
            super(dateMiseEnService, rendementMensuel);
            this.densite = densite;
            this.typeGaz = typeGaz;
        }
     
        public double getDensite() {
            return densite;
        }
        public void setDensite(double densite) {
            this.densite = densite;
        }
     
        public String getTypeGaz() {
            return typeGaz;
        }
        public void setTypeGaz(String typeGaz) {
            this.typeGaz = typeGaz;
        }
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    @Entity
    @PrimaryKeyJoinColumn(name="id", foreignKey=@ForeignKey(name = "FK_Mineraux_Guisement"))
    @DiscriminatorValue("mineraux")
    @Table(name="Mineraux")
    @OnDelete(action = OnDeleteAction.CASCADE)
    public class Mineraux extends Gisement {
        private double purete;
        @Column(name="type_mineraux")
        private String typeMineraux;
     
        public Mineraux(){
            //
        }
        public Mineraux(LocalDate dateMiseEnService, int rendementMensuel, double purete, String typeMineraux) {
            super(dateMiseEnService, rendementMensuel);
            this.purete = purete;
            this.typeMineraux = typeMineraux;
        }
     
        public double getPurete() {
            return purete;
        }
        public void setPurete(double purete) {
            this.purete = purete;
        }
     
        public String getTypeMineraux() {
            return typeMineraux;
        }
        public void setTypeMineraux(String typeMineraux) {
            this.typeMineraux = typeMineraux;
        }
    }
    Ma classe "Equipe" qui a une relation ManyToOne bidirectionnelle avec Gisement. C'est à dire qu'une equipe ne travail que sur un gisement à la fois alors qu'un gisement peut avoir plusieurs équipes
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    import javax.persistence.*;
    import java.io.Serializable;
     
    @Entity
    public class Equipe implements Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        @ManyToOne
        // nom de la colonne qui sera une clef étrangère de Gisement DANS Equipe
        //@JoinColumn(name="id_gisement", nullable = false)
        @JoinColumn(name="id_gisement")
        private Gisement gisement;
        private String nom;
     
        public Equipe(){
            //
        }
        public Equipe(String nom, Gisement gisement) {
            this.nom = nom;
            this.gisement = gisement;
        }
     
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
     
        public Gisement getGisement() {
            return gisement;
        }
        public void setGisement(Gisement gisement) {
            this.gisement = gisement;
        }
     
        public String getNom() {
            return nom;
        }
        public void setNom(String nom) {
            this.nom = nom;
        }
    }
    Ma classe "AbstractDao" :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
     
    public abstract class AbstractDao<T> {
        //protected static final Logger LOGGER = LogManager.getLogger(AbstractDao.class);
        protected Class<T> modelClass;
     
        private SessionFactory sf;
        private InitSessionFactory i = new InitSessionFactory();
     
        public void setmodelClass(Class<T> modelClass) {
            this.modelClass = modelClass;
     
            sf = i.getSessionFactory();
        }
     
        protected final Session getSession() {
            Session session = null;
            try {
                session = this.sf.getCurrentSession();
            } catch (Exception e) {
                //LOGGER.error(e);
            }
     
            if (session == null)
                session = sf.openSession();
     
            return session;
     
        }
     
        protected final Transaction getTransaction(Session session) {
            Transaction tx = session.getTransaction();
            if (!TransactionStatus.ACTIVE.equals(tx.getStatus()))
                tx = session.beginTransaction();
     
            return tx;
        }
     
        public final void create(T obj) {
            Session session = this.getSession();
            Transaction tx = null;
            try {
                tx = this.getTransaction(session);
                session.save(obj);
                tx.commit();
            } catch (RuntimeException e) {
                if (tx != null)
                    tx.rollback();
                throw e; // Gérer le message (log, affichage, etc.)
            } finally {
                //session.close();
                session.close();
            }
           // return id;
        }
     
        public final void delete(T obj) {
            Session session = this.getSession();
            Transaction tx = null;
            try {
                tx = this.getTransaction(session);
                session.delete(obj);
                tx.commit();
            } catch (RuntimeException e) {
                if (tx != null)
                    tx.rollback();
                throw e; // Gérer le message (log, affichage, etc.)
            } finally {
                session.close();
     
            }
     
        }
     
        public final void update(T obj) {
            Session session = null;
            Transaction tx = null;
            try {
                session = this.getSession();
                tx = this.getTransaction(session);
                session.saveOrUpdate(obj);
                tx.commit();
            } catch (RuntimeException e) {
                if (tx != null)
                    tx.rollback();
                throw e; // Gérer le message (log, affichage, etc.)
            } finally {
                session.close();
            }
        }
     
        public T getById(int id) {
            return getSession().get(modelClass, id);
        }
        public T getById(String id) {
            return getSession().get(modelClass, id);
        }
     
        @SuppressWarnings("unchecked")
        public List<T> getAll() {
            return getSession().createQuery("from " +
                    modelClass.getName()).list();
        }
     
     
        public abstract List<T> search(T criteria);
     
    }
    Ainsi que la classe "InitSessionFactory :
    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
    23
    24
    25
    26
    27
    28
     
    import org.hibernate.SessionFactory;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
     
    public class InitSessionFactory {
        private SessionFactory sessionFactory;
     
        public InitSessionFactory() {
            //configuration.configure("classpath:com/resources/hibernate.cfg.xml");
            Configuration configuration = new Configuration().configure("/hibernate.cfg.xml");
            //Différentes classes
            //configuration.addAnnotatedClass(.class);
     
            configuration.addAnnotatedClass(Equipe.class);
            configuration.addAnnotatedClass(Gisement.class);
            configuration.addAnnotatedClass(Mineraux.class);
            configuration.addAnnotatedClass(Gaz.class);
     
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        }
     
        protected SessionFactory getSessionFactory() {
            return sessionFactory;
        }
    }
    GisementDAO qui l'implémente :
    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
     
    import Models.Gisement;
    import java.util.List;
     
    public class GisementDao  extends AbstractDao<Gisement> {
     
        public GisementDao() {
            this.setmodelClass(Gisement.class);
        }
     
        //pas complet
        @Override
        public List<Gisement> search(Gisement criteria) {
            return null;
        }
    }
    La partie de mon code qui fait appel à la fonction "delete" de mon DAO lorsque je veux supprimer un gisement (il fait suite à un formulaire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    if(formType.equals("supprimerGisement")) {
                Integer idGisement = Integer.parseInt(request.getParameter("gisementEnCours"));
                String typeGisement = gisementDao.getById(idGisement).getTypeGisement();
     
                if(typeGisement.equals("mineraux")) {
                    Mineraux mineraux = minerauxDao.getById(idGisement);
                    minerauxDao.delete(mineraux);
     
                }else if(typeGisement.equals("gaz")) {
                    Gaz gaz = gazDao.getById(idGisement);
                    gazDao.delete(gaz);
                }
            }

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par tomateSalade Voir le message
    Je me permets de bump mon poste.
    Petite up

Discussions similaires

  1. [Data] illegally attempted to associate a proxy with two open Sessions
    Par lotfi-g dans le forum Spring
    Réponses: 1
    Dernier message: 02/01/2011, 14h24
  2. [Hibernate] illegally attempted to associate a proxy with two open Sessions
    Par NeoKript dans le forum Persistance des données
    Réponses: 7
    Dernier message: 23/11/2010, 22h40
  3. Réponses: 3
    Dernier message: 28/02/2007, 16h21
  4. Réponses: 2
    Dernier message: 13/10/2006, 17h38
  5. Réponses: 4
    Dernier message: 20/07/2006, 17h26

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