2 Replies Latest reply on Jun 3, 2006 2:22 AM by tsar_bomba

    Newbie needs advice on Lazy collections

      I'm well aware of the "problem" of session context and the issue w/ calling a lazy collection outside of that context in Hibernate.

      What I'm looking for is advice - some simple insight into techniques to get around the limitations in EJB3/Hibernate lazy collections to make life easier, if possible.

      I realize that if I'm calling a single object in the stateless session bean, I can get the lazy collection by simply calling the size() method of the collection...and then return it to the view and life is good.

      However, what if I've got a hierarchy like this:

      Product -> List -> List

      So I've got a Product that has many Configurations, each Configuration can have many Prices....a one-to-many w/ each having its own one-to-many.

      My particular headache happens when I call a List and I need to display the Price for each product....will I have to loop through each Product, call size() on the List, then loop through each Configuration and call size() on List??

      Before JBoss 4.0.4.GA (RC1, CR2) I had eager fetching for both the Configuration and the Price collections and it seemed to work...but obviously something changed in GA to prevent that since it throws an exception on my when deploying the app.

      I got around this when learning Hibernate by simply not using the object hierarchy that is queried automatically and just calling separate lists by the parent object's ID value...but that just generates even more queries.

      Is there some way to make the session run longer in the container so it's available to the lazily-loaded collections? Again, forgive me for my ignorance, I'm just shooting in the dark.

      When I started off on learning EJB3 I assumed there'd be some magic in the container to prevent lazy-loading session management issues like I experienced in plain Hibernate (outside of a J2EE container.)

      Any advice would be greatly appreciated, thanks! My new EJB3 O'Reilly book is on the way but until then, please advise!

        • 1. Re: Newbie needs advice on Lazy collections
          echon

          if you know your use-cases lazy-loading is not a big problem.

          If you know exactly what to load use a facade with where the business methods load what you want. Inside the BM use the EJB QueryLanguage like

          from User u left join fetch u.companys as c left join fetch c.country where u.login=:login

          Problem here is you have to be carefull, if you have more than one left join, because you get a the scalar as result (like in this case where you (can) get the user x times, also if login is unique)

          Another way to do so is to make your faced as Statefully SessionBean (SFSB) with a longrunning PersistentContext. In this you get persistent (not detached) object you can work with. Also here you should do as much as possible with a left join fetch from the associated entities you need in your use-case (one join is better than execute a Select each time - if you have products you don't want a select for each category).
          With a SFSB you control the lifecycle of the bean and the persistentcontext. So you have "manually" remove the bean by calling a method annotated with @Remove.

          For SFSB and Extended PersistenceContext read the JBoss EJB 3 Trailblazer. If you a familiar with JSF it is a good idea to have a deep
          look at JBoss Seam (first choice for a good web-application).

          Regards

          Peter

          • 2. Re: Newbie needs advice on Lazy collections

             

            "echon" wrote:
            if you know your use-cases lazy-loading is not a big problem.

            If you know exactly what to load use a facade with where the business methods load what you want. Inside the BM use the EJB QueryLanguage like
            from User u left join fetch u.companys as c left join fetch c.country where u.login=:login

            Problem here is you have to be carefull, if you have more than one left join, because you get a the scalar as result (like in this case where you (can) get the user x times, also if login is unique)

            Another way to do so is to make your faced as Statefully SessionBean (SFSB) with a longrunning PersistentContext. In this you get persistent (not detached) object you can work with. Also here you should do as much as possible with a left join fetch from the associated entities you need in your use-case (one join is better than execute a Select each time - if you have products you don't want a select for each category).
            With a SFSB you control the lifecycle of the bean and the persistentcontext. So you have "manually" remove the bean by calling a method annotated with @Remove.

            For SFSB and Extended PersistenceContext read the JBoss EJB 3 Trailblazer. If you a familiar with JSF it is a good idea to have a deep
            look at JBoss Seam (first choice for a good web-application).

            Regards

            Peter


            Peter, thank you, this really helped. I wasn't aware of the left join fetch option, it solves (most) of my problems and was incredibly simple. I must have been looking in all the wrong places for this information!

            Thanks again!