-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Many to many bidirectionnelle : LazyInitializationException
PostPosted: Tue May 10, 2005 5:42 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
Salut,

J'ai une relation many to many qui provoque l'erreur ci-dessous.

J'ai un objet business "job" qui représente une demande de service. A cette demande de service peuvent êtres associés plusieurs personnes de contact (objet business "Contact", propriété "contactsForClient") qui peuvent elles-même être associées à plusieurs demandes de service.

Dans Job.hbm.xml (cf ci-dessous), j'ai mis "inverse=true".

Voici le code de la méthode "setContactsForClient" de mon objet Job :
Code:
   public void setContactsForClient( Collection contactsForClient )
   {
      //déassocier les anciens contacts :
      for ( Iterator iter = this.contactsForClient.iterator(); iter.hasNext(); )
      {
         Contact contact = (Contact)iter.next();
         contact.removeJob( this );
      }
      //associer les nouveaux contacts
      for ( Iterator iter = contactsForClient.iterator(); iter.hasNext(); )
      {
         Contact contact = (Contact)iter.next();
         contact.addJob( this );
      }
      this.contactsForClient = contactsForClient;
   }


Est-ce que mon approche est mauvaise ?

Merci d'avance pour votre aide
Lilian

Hibernate version:
3.0.2

Mapping documents:
Contact.hbm.xml :
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>

   <subclass
      name="bab.admin.model.persistent.Contact"
      discriminator-value="contact"
      extends="bab.admin.model.persistent.IParty" >
   
      <bag
         name="jobs"
         table="t_clientcontact"
         cascade="all" lazy="true">
         
         <key column="partyId"  />
         
         <many-to-many
            class="bab.admin.model.persistent.Job"
            column="serviceId" >
         </many-to-many>
      </bag>
      
      
      <join table="t_person">
      
         <key column="partyId" />
         
         <property name="sex" />
         <property name="title" />
         <property name="maritalStatus" column="maritalStatusCode" />
         <property name="birthdate" />
         
         <component
            name="fullname"
            class="bab.admin.model.persistent.Fullname" >
            <property name="firstname" />
            <property name="lastname" />
         </component>
         
      </join>
      
   </subclass>
   
</hibernate-mapping>


Job.hbm.xml :
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
   <class name="bab.admin.model.persistent.Job" table="t_service"
      dynamic-update="false" dynamic-insert="false"
      select-before-update="false" optimistic-lock="version">

      <id name="id" column="serviceId" type="java.lang.Integer">
         <generator class="native">
         </generator>
      </id>
      
      <many-to-one
         name="client"
         column="clientPartyId"
         lazy="true" /><!-- modifié à true par LR 27 avril 05 -->
      <many-to-one
         name="contactForBAB"
         column="employeePartyId"
         lazy="true" /><!-- modifié à true par LR 27 avril 05 -->
         
      <bag
         name="contactsForClient"
         table="t_clientcontact"
         inverse="true"
         cascade="all">
         
         <key column="serviceId"  />
         
         <many-to-many
            class="bab.admin.model.persistent.Contact"
            column="partyId" />
      </bag>
      
      <set
         name="periods"
         inverse="true"
         cascade="all"
         order-by="startDate">
      
         <key column="serviceId" />
         
         <one-to-many
            class="bab.admin.model.persistent.JobPeriod" />
      </set>
      
      <set
         name="jobWorkers"
         inverse="true"
         cascade="all" >
      
         <key column="serviceId" />
         
         <one-to-many
            class="bab.admin.model.persistent.JobWorker" />
      
      </set>
         
      <!--<many-to-one
         name="contactForClient"
         column="clientResponsiblePartyId"
         class="bab.admin.model.persistent.Contact"
         cascade="save-update"
         lazy="false" /> -->
         
      <many-to-one
         name="tarif"
         column="tarifId"
         cascade="all"
         lazy="true" /><!-- modifié à true par LR 27 avril 05 -->
            
      <one-to-one name="evaluation" />
      
      <many-to-one
         name="address"
         cascade="all"
         column="contactPointId" />

      <property name="fileId" />
      
      <property
         name="title"
         column="jobTitle" />
         
      <property
         name="description"
         column="jobDescription" />
         
      <property
         name="begin"
         column="contactDate" />
         
      <property
         name="close"
         column="closeDate" />
         
      <property
         name="contract"
         column="contractDate" />
         
      <property
         name="feedback"
         column="babFeedback" />
         
      <property
         name="comment" />
         
         
      <component name="invoice">

         <property
            name="sent"
            column="invoiceDate" />
            
         <property
            name="number"
            column="invoiceNumber" />
            
         <property name="comment"
            column="invoiceComment" />
         
         <property name="otherCharges" />
         
         <property name="otherChargesDescription" />
         
      </component>
            
            
            
      
   </class>

</hibernate-mapping>


Exemple de code provoquant l'erreur :
Code:
public void testFindAll()
   {
      Collection objects = dao.findAll( Contact.class );
      
      assertNotNull( objects );
      
      for ( Iterator iter = objects.iterator(); iter.hasNext(); )
      {
         Contact o = (Contact)iter.next();
         System.out.println( o.getFullname() );
         System.out.println( "==========================" );
         Collection jobs = o.getJobs();
         for ( Iterator iterator = jobs.iterator(); iterator.hasNext(); )
         {
            Job job = (Job)iterator.next();
            System.out.println( "    " +job.getTitle() );
         }
      }
   }


Full stack trace of any exception that occurs:
11:08:06,379 ERROR LazyInitializationException:19 - cannot access loading collection
org.hibernate.LazyInitializationException: cannot access loading collection
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:168)
at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:61)
at org.hibernate.collection.PersistentBag.add(PersistentBag.java:267)
at bab.admin.model.persistent.Contact.addJob(Contact.java:75)
at bab.admin.model.persistent.Job.setContactsForClient(Job.java:425)
at bab.admin.model.persistent.Job$$BulkBeanByCGLIB$$9a708169.setPropertyValues(<generated>)
at org.hibernate.tuple.PojoTuplizer.setPropertyValuesWithOptimizer(PojoTuplizer.java:200)
at org.hibernate.tuple.PojoTuplizer.setPropertyValues(PojoTuplizer.java:173)
at org.hibernate.persister.entity.BasicEntityPersister.setPropertyValues(BasicEntityPersister.java:2900)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:113)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:506)
at org.hibernate.loader.Loader.doQuery(Loader.java:415)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:210)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1396)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:107)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:483)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1354)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:171)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:242)
at bab.admin.model.dao.DefaultDAOTest.testFindAll(DefaultDAOTest.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:474)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:342)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:194)

Name and version of the database you are using:
MySQL 4.1

The generated SQL (show_sql=true):
Hibernate: select this_.partyId as partyId0_, this_.comment as comment4_0_, this_1_.sex as sex6_0_, this_1_.title as title6_0_, this_1_.maritalStatusCode as maritalS4_6_0_, this_1_.birthdate as birthdate6_0_, this_1_.firstname as firstname6_0_, this_1_.lastname as lastname6_0_ from t_party this_ inner join t_person this_1_ on this_.partyId=this_1_.partyId where this_.partyType='contact'
Hibernate: select jobs0_.partyId as partyId__, jobs0_.serviceId as serviceId__, job1_.serviceId as serviceId0_, job1_.clientPartyId as clientPa2_11_0_, job1_.employeePartyId as employee3_11_0_, job1_.tarifId as tarifId11_0_, job1_.contactPointId as contactP5_11_0_, job1_.fileId as fileId11_0_, job1_.jobTitle as jobTitle11_0_, job1_.jobDescription as jobDescr8_11_0_, job1_.contactDate as contactD9_11_0_, job1_.closeDate as closeDate11_0_, job1_.contractDate as contrac11_11_0_, job1_.babFeedback as babFeed12_11_0_, job1_.comment as comment11_0_, job1_.invoiceDate as invoice14_11_0_, job1_.invoiceNumber as invoice15_11_0_, job1_.invoiceComment as invoice16_11_0_, job1_.otherCharges as otherCh17_11_0_, job1_.otherChargesDescription as otherCh18_11_0_, clienteval2_.evaluationId as evaluati1_1_, clienteval2_.content as content9_1_, clienteval2_.positiveYN as positiveYN9_1_, job3_.serviceId as serviceId2_, job3_.clientPartyId as clientPa2_11_2_, job3_.employeePartyId as employee3_11_2_, job3_.tarifId as tarifId11_2_, job3_.contactPointId as contactP5_11_2_, job3_.fileId as fileId11_2_, job3_.jobTitle as jobTitle11_2_, job3_.jobDescription as jobDescr8_11_2_, job3_.contactDate as contactD9_11_2_, job3_.closeDate as closeDate11_2_, job3_.contractDate as contrac11_11_2_, job3_.babFeedback as babFeed12_11_2_, job3_.comment as comment11_2_, job3_.invoiceDate as invoice14_11_2_, job3_.invoiceNumber as invoice15_11_2_, job3_.invoiceComment as invoice16_11_2_, job3_.otherCharges as otherCh17_11_2_, job3_.otherChargesDescription as otherCh18_11_2_ from t_clientcontact jobs0_ inner join t_service job1_ on jobs0_.serviceId=job1_.serviceId left outer join t_evaluation clienteval2_ on job1_.serviceId=clienteval2_.evaluationId left outer join t_service job3_ on clienteval2_.evaluationId=job3_.serviceId where jobs0_.partyId=?
Hibernate: select contactsfo0_.serviceId as serviceId__, contactsfo0_.partyId as partyId__, contact1_.partyId as partyId0_, contact1_.comment as comment4_0_, contact1_1_.sex as sex6_0_, contact1_1_.title as title6_0_, contact1_1_.maritalStatusCode as maritalS4_6_0_, contact1_1_.birthdate as birthdate6_0_, contact1_1_.firstname as firstname6_0_, contact1_1_.lastname as lastname6_0_ from t_clientcontact contactsfo0_ inner join t_party contact1_ on contactsfo0_.partyId=contact1_.partyId left outer join t_person contact1_1_ on contact1_.partyId=contact1_1_.partyId where contactsfo0_.serviceId=?


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 10, 2005 11:20 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
Bonjour,

Le problème est le suivant:

Code:
<bag
         name="jobs"
         table="t_clientcontact"
         cascade="all" lazy="true">         
         <key column="partyId"  />
         <many-to-many class="bab.admin.model.persistent.Job"   column="serviceId" >
</many-to-many>
</bag>


Dans le fichier de mapping, vous avez mis: lazy="true", ce qui signifie qu'hibernate ne tentera de charger les données relatives à la relation "jobs" que lorsque vous tenterez de parcourir la relation contact.getJobs().

Pour qu'une relation lazy soit hydratée sur demande, il faut que l'appel de méthode (dans votre cas: getJobs) soit fait à l'intérieur du scope d'un object Session.

Dans votre test unitaire: j'imagine que le dao.findAll obtient une session, fait la requête et, ensuite referme la session. Ainsi, lorsque vous exécutez la commande o.getJobs(), la session n'est plus valide et hibernate ne peut faire le "select * from jobs where..."

Code:
public void testFindAll()
   {
      Collection objects = dao.findAll( Contact.class );
     
      assertNotNull( objects );
     
      for ( Iterator iter = objects.iterator(); iter.hasNext(); )
      {
         Contact o = (Contact)iter.next();
         System.out.println( o.getFullname() );
         System.out.println( "==========================" );
         Collection jobs = o.getJobs();
         for ( Iterator iterator = jobs.iterator(); iterator.hasNext(); )
         {
            Job job = (Job)iterator.next();
            System.out.println( "    " +job.getTitle() );
         }
      }
   }


Je vous suggère d'utiliser le pattern de commande (Command Pattern) et de passer la session à votre commande de DAO. Ainsi, vous pourrez ouvrir votre session dans le setUp() de votre test unitaire et la relâcher dans le tearDown(). Votre relation pourra alors être correctement naviguée.

J'espère que cela vous aidera.

Vincent Giguère

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 11, 2005 4:13 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
Merci pour ta réponse.

En réalité, je travaille sur une application J2EE et l'ouverture et la fermeture de la session se fait dans un Filter qui est appelé à chaque requête.

Le code de ma méthode findAll est le suivant :
Code:
   public Collection findAll( Class clazz ) throws InfrastructureException
   {
      try
      {
         Session session = HibernateUtil.getSession();
         Criteria crit = session.createCriteria( clazz );
         return crit.list();
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
   }


La session n'est pas refermée, elle est stockée dans une variable ThreadLocal (cf code de HibernateUtil ci-dessous) et, dans le cas du test unitaire, je ne la referme pas (dans le cas de l'application J2EE, elle est refermée dans le Filter).

Donc si j'ai bien compris, ce que tu as décrit n'est pas correct pour ce cas précis.

Dans la méthode getSession de HibernatUtil, j'ai mis un log.info qui m'affiche une ligne dans la console lorsqu'une session est ouverte, et la session n'est ouverte qu'une seule fois.

J'espère que tu voudras bien me faire partager ton expérience encore un peu pour me permettre d'avancer, en attendant je vais essayer de contourner le problème en enlevant le "lazy=true".

Merci pour ton aide
A+ Lilian

HibernateUtil :
Code:
package bab.admin.model;

import org.apache.commons.logging.*;
import org.hibernate.*;
import org.hibernate.cfg.*;

import bab.admin.model.exceptions.*;

public class HibernateUtil
{

   private static Log log = LogFactory.getLog( HibernateUtil.class );
   private static int configurationReaded = 0;
   private static int openedSessions = 0;

   private static transient Configuration configuration;
   private static transient  SessionFactory sessionFactory;
   private static transient  final ThreadLocal threadSession = new ThreadLocal();
   private static transient  final ThreadLocal threadTransaction = new ThreadLocal();
   private static transient  final ThreadLocal threadInterceptor = new ThreadLocal();

   // Create the initial SessionFactory from the default configuration files
   static
   {
      try
      {
         configuration = new Configuration();
         sessionFactory = configuration.configure().buildSessionFactory();
         log.debug( "configuration lue : " +(++configurationReaded)+ " fois." );
         // We could also let Hibernate bind it to JNDI:
         // configuration.configure().buildSessionFactory()
      }
      catch ( Throwable ex )
      {
         // We have to catch Throwable, otherwise we will miss
         // NoClassDefFoundError and other subclasses of Error
         log.error( "Building SessionFactory failed.", ex );
         throw new ExceptionInInitializerError( ex );
      }
   }

   /**
    * Returns the SessionFactory used for this static class.
    *
    * @return SessionFactory
    */
   public static SessionFactory getSessionFactory()
   {
      /* Instead of a static variable, use JNDI:
       SessionFactory sessions = null;
       try {
       Context ctx = new InitialContext();
       String jndiName = "java:hibernate/HibernateFactory";
       sessions = (SessionFactory)ctx.lookup(jndiName);
       } catch (NamingException ex) {
       throw new InfrastructureException(ex);
       }
       return sessions;
       */
      return sessionFactory;
   }

   /**
    * Returns the original Hibernate configuration.
    *
    * @return Configuration
    */
   public static Configuration getConfiguration()
   {
      return configuration;
   }

   /**
    * Rebuild the SessionFactory with the static Configuration.
    *
    */
   public static void rebuildSessionFactory() throws InfrastructureException
   {
      synchronized ( sessionFactory )
      {
         try
         {
            sessionFactory = getConfiguration().buildSessionFactory();
         }
         catch ( Exception ex )
         {
            throw new InfrastructureException( ex );
         }
      }
   }

   /**
    * Rebuild the SessionFactory with the given Hibernate Configuration.
    *
    * @param cfg
    */
   public static void rebuildSessionFactory( Configuration cfg ) throws InfrastructureException
   {
      synchronized ( sessionFactory )
      {
         try
         {
            sessionFactory = cfg.buildSessionFactory();
            configuration = cfg;
         }
         catch ( Exception ex )
         {
            throw new InfrastructureException( ex );
         }
      }
   }

   /**
    * Retrieves the current Session local to the thread.
    * <p/>
    * If no Session is open, opens a new Session for the running thread.
    *
    * @return Session
    */
   public static Session getSession() throws InfrastructureException
   {log.debug( "HibernateUtil.getSession" );
      Session s = (Session)threadSession.get();
      try
      {
         if ( s == null )
         {
            log.info( "Opening new Session for this thread. (" +(++openedSessions)+ " sessions ouvertes)" );
            if ( getInterceptor() != null )
            {
               log.info( "Using interceptor: " + getInterceptor().getClass() );
               s = getSessionFactory().openSession( getInterceptor() );
            }
            else
            {
               s = getSessionFactory().openSession();
            }
            threadSession.set( s );
         }
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
      return s;
   }

   /**
    * Closes the Session local to the thread.
    */
   public static void closeSession() throws InfrastructureException
   {
      try
      {
         Session s = (Session)threadSession.get();
         threadSession.set( null );
         if ( s != null && s.isOpen() )
         {
            log.info( "Closing Session of this thread. (" +(--openedSessions)+ " sessions ouvertes" );
            s.clear();
            s.close();
         }
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
   }

   /**
    * Start a new database transaction.
    */
   public static void beginTransaction() throws InfrastructureException
   {
      Transaction tx = (Transaction)threadTransaction.get();
      try
      {
         if ( tx == null )
         {
            System.out.println( "Début d'une nouvelle transaction pour ce Thread" );
            log.debug( "Starting new database transaction in this thread." );
            tx = getSession().beginTransaction();
            threadTransaction.set( tx );
         }
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
   }

   /**
    * Commit the database transaction.
    */
   public static void commitTransaction() throws InfrastructureException
   {
      Transaction tx = (Transaction)threadTransaction.get();
      try
      {
         if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() )
         {
            System.out.println( "Commit de la transaction pour ce thread" );
            log.debug( "Committing database transaction of this thread." );
            tx.commit();
         }
         threadTransaction.set( null );
      }
      catch ( HibernateException ex )
      {
         rollbackTransaction();
         throw new InfrastructureException( ex );
      }
   }

   /**
    * Commit the database transaction.
    */
   public static void rollbackTransaction() throws InfrastructureException
   {
      Transaction tx = (Transaction)threadTransaction.get();
      try
      {
         threadTransaction.set( null );
         if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() )
         {
            System.out.println( "Rollback de la transaction pour ce thread ");
            log.debug( "Tyring to rollback database transaction of this thread." );
            tx.rollback();
         }
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
      finally
      {
         closeSession();
      }
   }

   /**
    * Reconnects a Hibernate Session to the current Thread.
    *
    * @param session The Hibernate Session to be reconnected.
    */
   public static void reconnect( Session session ) throws InfrastructureException
   {
      try
      {
         System.out.println( "reconnect session");
         session.reconnect();
         threadSession.set( session );
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
   }

   /**
    * Disconnect and return Session from current Thread.
    *
    * @return Session the disconnected Session
    */
   public static Session disconnectSession() throws InfrastructureException
   {

      Session session = getSession();
      try
      {
         System.out.println( "disconnect session ");
         threadSession.set( null );
         if ( session.isConnected() && session.isOpen() ) session.disconnect();
      }
      catch ( HibernateException ex )
      {
         throw new InfrastructureException( ex );
      }
      return session;
   }

   /**
    * Register a Hibernate interceptor with the current thread.
    * <p>
    * Every Session opened is opened with this interceptor after
    * registration. Has no effect if the current Session of the
    * thread is already open, effective on next close()/getSession().
    */
   public static void registerInterceptor( Interceptor interceptor )
   {
      threadInterceptor.set( interceptor );
   }

   private static Interceptor getInterceptor()
   {
      Interceptor interceptor = (Interceptor)threadInterceptor.get();
      return interceptor;
   }

}


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 11, 2005 9:19 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
J'ai essayé de modifier mes deux fichiers de mapping : Job.hbm.xml et Contact.hbm.xml afin de mettre des deux coté le lazy à false mais ça n'a rien changé...

Comment se fait-il que je recoive une LazyInitializationException alors que "lazy=false" ?

Je cherche depuis des heures mais je n'arrive à rien, j'espère que quelqu'un voudra bien m'aider.

Merci d'avance
Lilian


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 11, 2005 9:53 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
Bonjour,

Vous avez raison, je suis allé voir le code de la classe AbstractPersistentCollection.java et le problème ne vient pas d'une mauvaise gestion de la session.

Code:
protected final void initialize(boolean writing) {
      if (!initialized) {
         if (initializing) throw new LazyInitializationException("cannot access loading collection");
         if ( isConnectedToSession() )  {
            if ( session.isConnected() ) {
               session.initializeCollection(this, writing);
            }
            else {
                    String name = (getCollectionSnapshot()!=null)?"("+getCollectionSnapshot().getRole()+")":"";
               throw new LazyInitializationException("failed to lazily initialize a collection " + name + " - session is disconnected");
            }
         }
         else {
                String name = (getCollectionSnapshot()!=null)?"("+getCollectionSnapshot().getRole()+")":"";
            throw new LazyInitializationException("failed to lazily initialize a collection " + name + " - no session or session was closed");
         }
      }
   }



En lisant le code de la classe, il semble que deux méthodes doivent être appelées beginRead() et endRead() (l'un fait initializing = true et l'autre initializing = false).

Je ne sais pas à quoi servent ces méthodes, mais il semble que vous tentiez de parcourir la relation entre le beginRead et le endRead... Ces méthodes sont redéfinies par les sousclasses.

Essayez de remplacer bag par set. Peut-être que c'est l'implantation de bag qui a un problème.

Laissez-moi savoir si cela fonctionne .

Bonne chance.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 11, 2005 11:56 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
Je viens d'essayer de changer bag en set mais le résultat est exactement le même...

J'espère que vous aurez une autre idée, car je débute sur Hibernate (et je n'ai pas non plus une très grande expérience de J2EE) et ce problème me dépasse complètement.

Quoi qu'il en soit, merci beaucoup pour votre aide
Salutations
Lilian


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 11, 2005 10:28 pm 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
Je n'ai plus d'idée. Votre problème est bizarre!! :(
J'utilise hibernate depuis 6-8 mois et j'utilise abondamment le même genre de mapping que vous et je n'ai jamais eu un problème de la sorte...

Je crois que vous feriez mieux de reposer votre question en anglais sur le forum anglophone. Vous rejoindrez certainement une plus grande communauté d'utilisateur.

Je crois qu'Anthony et Emmanuel sont francophones, mais j'ignore comment faire pour les contacter directement.

Bonne chance.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 12, 2005 4:08 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
vgiguere wrote:
Je n'ai plus d'idée. Votre problème est bizarre!! :(
J'utilise hibernate depuis 6-8 mois et j'utilise abondamment le même genre de mapping que vous et je n'ai jamais eu un problème de la sorte...

Je crois que vous feriez mieux de reposer votre question en anglais sur le forum anglophone. Vous rejoindrez certainement une plus grande communauté d'utilisateur.

Je crois qu'Anthony et Emmanuel sont francophones, mais j'ignore comment faire pour les contacter directement.

Bonne chance.


Merci pour votre aide, je vais chercher encore et tenter ma chance sur le forum anglophone.

Je posterai ici si je trouve une solution

Lilian


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 13, 2005 4:33 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Ne manimule pas la collection dans le setter.
Le setter doit se limiter à
setCollection(Collection col) {
this.collection = col;
}

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 13, 2005 6:31 am 
Beginner
Beginner

Joined: Wed Mar 30, 2005 5:41 am
Posts: 40
emmanuel wrote:
Ne manimule pas la collection dans le setter.
Le setter doit se limiter à
setCollection(Collection col) {
this.collection = col;
}


Merci pour ta réponse,
J'ai refléchi à ce que tu as dit et j'ai modifié mon code...

Comme dans Job.hbm.xml j'avais associé les contacts avec "inverse=true", dans la méthode setContactsForClient de la classe Job, je "désassociais" les contacts associés au job avant de réassocier les contacts de la collection passée en paramètre :

Code:
   public void setContactsForClient( Collection contactsForClient )
   {
      //déassocier les anciens contacts :
      Collection currentContacts = getContactsForClient();
      for ( Iterator iter = currentContacts.iterator(); iter.hasNext(); )
      {
         Contact contact = (Contact)iter.next();
         contact.removeJob( this );
      }
      //associer les nouveaux contacts
      for ( Iterator iter = contactsForClient.iterator(); iter.hasNext(); )
      {
         Contact contact = (Contact)iter.next();
         contact.addJob( this );
      }
      this.contactsForClient = contactsForClient;
   }


Maintenant, je ne fais plus que this.contactsForClient = contactsForClient et j'ai ajouté une méthode clearContactsForClient qui est appelée explicitement lorsque nécessaire afin de faire ce travail :
Code:
   public void clearContactsForClient()
   {
      Collection currentContacts = getContactsForClient();
      for ( Iterator iter = currentContacts.iterator(); iter.hasNext(); )
      {
         Contact contact = (Contact)iter.next();
         contact.removeJob( this );
      }
      setContactsForClient( new HashSet() );
   }


Ca a l'air de fonctionner, merci à tous pour votre aide.

A+Lilian


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 24, 2005 8:07 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
emmanuel wrote:
Ne manimule pas la collection dans le setter.
Le setter doit se limiter à
setCollection(Collection col) {
this.collection = col;
}


J'ai un code similaire provoquant le meme probleme.
Code:
    /**
     * @param function The function to set.
     */
    public void setFunction(Function function) {
        if (this.function != null)
            this.function.getBackups().remove(this);
        this.function;
        function.getBackups().add(this);
    }

function.backups est un Set. Le setter s'assure toujours ainsi que le lien entre le contenu du set function.backups et celui de la propriété backup.function reste cohérent. Il est bien sur évident que le comportement du setter devient abherrant au moment de l'hydratation (on demande à manipuler les données de function alors qu'elles n'ont pas encore été initialisées). Mais le reste du temps il est cohérent.

J'ai opté pour la solution suivante:
Code:
    /**
     * @param function The function to set.
     */
    public void setFunction(Function function) {
        if (this.function != null)
            this.function.getBackups().remove(this);
        setFunctionImpl(function);
        function.getBackups().add(this);
    }
    /**
     * @param function The function to set.
     */
    private void setFunctionImpl(Function function) {
        this.function = function;
    }

(dans le mapping hibernate je remplace la référence à la propriété function par la propriété functionImpl).

J'ignore si il s'agit de la méthode recommandée. Les remarques à ce sujet sont les bienvenues?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.