2 Replies Latest reply on May 27, 2009 2:48 PM by cpopetz

    Effective collection practices with session-scoped object

      I have a session-scoped User object with all lazy collections.


      Various pages in the application will access the collections of that User object - e.g. a favoriteCities.xhtml page would access the #{user.favoriteCities} lazily-loaded collection. And favoriteCountries.xhtml would access #{user.favoriteCountries}, another lazily-loaded collection.


      I could eagerly-load all collections upon the user's login, but that would be inefficient - after all, if the user only visits favoriteCountries.xhtml in a session, then I wouldn't want to also load his favorite CITIES. How can I write code to make it so that every time a new collection is accessed, it is loaded and added to the existing user object?


      So when the user accesses favoriteCities.xhtml, the favoriteCities collection is loaded and added to User instance u1. Then when the user accesses favoriteCountries.xhtml, the favoriteCountries collection is loaded and also added to that same User instance u1.


      Here's the problem: By using user = entityManager.merge(user) and outjecting the user to the session scope, I'm overwriting the previous session-scoped user object and losing any collections that were already loaded. i.e. If I accessed favoriteCities.xhtml then favoriteCountries.xhtml, then the session-scoped User with the cities collection loaded is overwritten with a User object with a countries collection but no cities collection.


      And by using user = entityManager.merge(user) and NOT outjecting the user to the session scope, the session-scoped user remains the same, but the loaded collection doesn't become part of that object.


      The whole problem is solved by eagerly loading ALL collections upon user login, but that's just so inefficient and unnecessary. How can I achieve the desired effect?

        • 1. Re: Effective collection practices with session-scoped object
          kapitanpetko

          If you are using Hibernate, it has an API (Hibernate.initialize) that lets you load a specified collection (preserving already loaded ones).


          Or you could use SMPC (Seam Managed Persistence Context) and forget about merge. That however, might be
          inefficient (depending on your app design).


          HTH



          • 2. Re: Effective collection practices with session-scoped object
            cpopetz

            This is really a JPA question, and AFAIK there is no way under the JPA spec to do what you're trying to do. 


            My suggestion is that if the collections in question are really large enough that loading them lazily and/or eagerly fetching them presents a speed or memory footprint issue, then they should be refactored to be more manageable, or you should use queries to only pull in the data you actually need.