-->
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.  [ 14 posts ] 
Author Message
 Post subject: Failed to lazily initialize a collection - no session
PostPosted: Mon May 24, 2004 12:39 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Hi all,

I'm having a problem I can't figure out the cause. Maybe I'm misusing my sessions.
I have a method in a persistent class that does the following:

Code:

   public void registraLivro(LivroImpl li)
      throws LivroJaExistente
   {
      ...

      try{
         Session s = sf.openSession();
         System.err.println(s.isOpen());  // This evaluates to "true"

         if(this.isbn2book.containsKey(li.isbn())){
            throw new LivroJaExistente();
         }
         
         ...
   }



isbn2book is a lazily loaded collection, it's a map actually. Whenever I try to do as above, I get the following exception:

Code:

01:25:32,383 ERROR LazyInitializationException:25 - Failed to lazily initialize a collection - no session or session was closed
net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
   at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
   at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
   at net.sf.hibernate.collection.Map.containsKey(Map.java:100)
   at Biblio.implementation.BibliotecaImpl.registraLivro(BibliotecaImpl.java:131)
   at Biblio.server.Main.makeLibrary(Main.java:160)
   at Biblio.server.Main.main(Main.java:55)


However, if I move the openSession statement to the caller code, I get no exception. Is this the way it's supposed to behave? I cannot open a session that manipulates an instance from inside that instance? An instance be self-contained? Is this like that to force me to decouple the persistent state from the handler code (or maybe to prevent an instance from saving itself)? Is there any workaround?

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 8:20 am 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
Maybe you are using an lazy="true" flag for your child object and you must initialize them befor using.
Look in the documentation about Parent child and lazy initialization.
Could you give more details about mapping files and java source code.

kind regards


Top
 Profile  
 
 Post subject: Please assist again! :-)
PostPosted: Mon May 24, 2004 9:51 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Hi subich!

Thanks for the quick response! Well, I'm not using lazy=true for my child object. Actually, the instance that gets queried for its "isbn" in my example is transient - it hasn't been saved at all - so I believe it doesn't have to be initialized. The parent object, however, is persistent and seems to be failing to initialize properly even with an open session. The collection that throws the exception is 'isbn2book'.

My guess is that perhaps I cannot open a session from a method in a persistent object and try to access a lazily initialized collection (which is an attribute of that same object). Maybe hibernate associates some sort context info with the session, introducing this issue.

I'll paste in the mapping files now, if you need any other info I'll be glad to supply it!

Best regards!

Parent:

Code:

<hibernate-mapping>
    <class
        name="Biblio.implementation.BibliotecaImpl"
        table="BIBLIOTECA"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="id"
            column="biblio_id"
            type="int"
        >
            <generator class="native">
            </generator>
        </id>

        <property
            name="nome"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="NOME"
        />

        <property
            name="cidade"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="CIDADE"
        />

        <property
            name="estado"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="ESTADO"
        />

        <map
            name="isbn2book"
            lazy="true"
            sort="unsorted"
            inverse="false"
            cascade="all-delete-orphan"
        >

              <key
                  column="BIBLIO_ID"
              >
              </key>

              <index
                  column="ISBN"
                  type="string"
              />

              <one-to-many
                  class="Biblio.implementation.LivroImpl"
              />
        </map>

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-BibliotecaImpl.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>


Child

Code:

<hibernate-mapping>
    <class
        name="Biblio.implementation.LivroImpl"
        table="LIVRO"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="livro_hib_id"
            column="LIVRO_ID"
            type="long"
        >
            <generator class="native">
            </generator>
        </id>

        <array
            name="autores"
            inverse="false"
            cascade="none"
        >

              <key
                  column="LIVRO_ID"
              >
              </key>

              <index
                  column="NDX_AUTOR"
              />

              <element
                  column="AUTOR"
                  type="string"
                  not-null="false"
                  unique="false"
              />

        </array>

        <property
            name="exid"
            type="int"
            update="true"
            insert="true"
            access="property"
            column="ATTRIB_ID_EXEMPLAR"
        />

        <map
            name="id2exemplar"
            lazy="true"
            sort="unsorted"
            inverse="false"
            cascade="all-delete-orphan"
        >

              <key
                  column="livro_hib_id"
              >
              </key>

              <index
                  column="chave_exemplar"
                  type="string"
              />

              <one-to-many
                  class="Biblio.implementation.ExemplarDeLivroImpl"
              />
        </map>

        <property
            name="isbn"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="ISBN"
        />

        <many-to-one
            name="parent"
            class="Biblio.implementation.BibliotecaImpl"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="BIB_PARENT"
        />

        <property
            name="titulo"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="TITULO"
        />

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-LivroImpl.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 10:15 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Here is another thing I've noticed.
I said before that if I moved the openSession to the caller code, that everything would work all right. Well, it's not true - I must "forget" to close the session I opened to load the parent instance if things are to work. In the code below, I begin by opening a session. If I close it, then the call to "registraLivro" (the last on my code) fails (I've sent the code earlier), even though I've opened a session *before* accessing the lazily loaded collection.

What is happening?

[code]

BibliotecaImpl bib;
Session s = sf.openSession();

List biblist = s.find("from BibliotecaImpl as bib where bib.nome = ? and bib.cidade = ? and bib.estado = ?",
new Object[] {"Carlos Lyra", "S


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 10:56 am 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
In your mapping files all your Map are lazy="true...
I try to find a solution for your problem but I m at work now.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:00 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Oh, you meant the collections! Yes, those are lazy. I thought you meant a lazy child attribute. Okay, thanks a bunch! I'll be waiting for you response.

Cheers,


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:08 am 
Newbie

Joined: Tue May 11, 2004 11:24 pm
Posts: 5
Hey... ok, I am a beginner in Hibernate like yourself (and seeing as I am not up to child/parent things, even more so!), so take everything I say with a grain of salt.

First up, why do you want to create a session from within the persistant class? There's something crazy to me about having a box that has inside it the door to outside the room the box is in.

Or something like that.

Anyway, a quick glance at the hibernate tutorial on page 5 notes:

...just make sure your sessionFactory is only created once... (bottom of the page)

BUT if you are holding this inside an object, then I am assuming that each time you access/create an object, you are also probably creating a sessionFactory object - which you aren't allowed to do.

I might recommend moving the whole sessionFactory/session thing away from you persistant class, and instead using a handy static class - and look, there is one on page 6 of the hibernate tutorial!

Put that up your flagpole, and tell me if it scares off the exception demons.[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:15 am 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
you are right bha'ral


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:20 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Hi!

Quote:
First up, why do you want to create a session from within the persistant class? There's something crazy to me about having a box that has inside it the door to outside the room the box is in.


Indeed, that might sound strange at first, but the problem is that I'm working with CORBA objects and so the hibernate access code must be contained inside the servant objects. This is why I need to be able to open a Session from inside the method call, since I'm not the one who is calling and my caller doesn't know I'm using hibernate.

Another reason I can think of would be if you're writing a framework or library which stores it's persistent state using hibernate and don't want your user to see it (though I can think of other, arguably better, approaches to it).

Quote:
...just make sure your sessionFactory is only created once... (bottom of the page)


Nope, I store the reference to the sessionFactory in a sort of a directory service. It's only created once.

Am I missing something here?

Cheers,


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:34 am 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
giuliano, where do you put your hibernate business source code?
Not in the POJO?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 11:58 am 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
The business source code is in the pojo(s), but I also need a part of the access code machinery (creating sessions, etc, etc) to be contained inside the "pojo" in some (but not all) methods. Think of my objects as a large fa


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 12:12 pm 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
Don't put your business code into POJO's, create a facade with static method for example and call them from CORBA, EJB, framework...
Your architecture if I understand well seems strange.
I can give you my msn if you want to talk about this.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 24, 2004 12:47 pm 
Newbie

Joined: Thu May 20, 2004 12:24 pm
Posts: 9
Location: Brazil
Sorry, maybe I didn't understand what you meant by business code. I agree with you when you say the architecture is strange - there isn't a clear disctinction of where the fa


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 25, 2004 4:01 am 
Senior
Senior

Joined: Fri Nov 21, 2003 5:55 am
Posts: 155
Ok I think I understand your problem, I had done the same kind of project for Belgacom with an Alcatel 5620 equipment, Alcatel give ma a Corba framework to access Corba Server and I wrote a Session EJB to access these method througout my JBoss app server.
If you use JBoss, Tomcat or something else, I don't know why you can't use a facade pattern to access Hibernate?

This is my Msn opensynapse@yahoo.fr


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 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.