Uploaded image for project: 'NHibernate'
  1. NHibernate
  2. NH-195

Child collections are not being stored in the second level cache

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: beta-0.7
    • Fix Version/s: beta-0.7
    • Component/s: Core
    • Labels:
      None
    • Environment:

      Description

      Logging showed that child collections were being loaded from the database with every page hit, although individual entities are successfully stored in the cache. This happens regardless of whether or not the child collections are also being lazy loaded.

      Further investigation indicates that NHibernate is looking for child collections in the cache but not saving them.

        Gliffy Diagrams

          Attachments

            Activity

            Hide
            jammycakes James McKay added a comment -

            I have managed to correct this issue by changing the implementation of NHibernate.Loader.Loader to the following, although I have not performed exhaustive tests on this:

            protected IList LoadCollection(
            ISessionImplementor session,
            object id,
            IType type,
            object owner,
            PersistentCollection collection )
            {
            QueryParameters qp = new QueryParameters( new IType[ ]

            {type}

            , new object[ ]

            {id}

            );
            IList result = DoFind( session, qp, null, null, collection, owner, true );
            this.CollectionPersister.Cache(id, collection, session);
            return result;
            }

            Show
            jammycakes James McKay added a comment - I have managed to correct this issue by changing the implementation of NHibernate.Loader.Loader to the following, although I have not performed exhaustive tests on this: protected IList LoadCollection( ISessionImplementor session, object id, IType type, object owner, PersistentCollection collection ) { QueryParameters qp = new QueryParameters( new IType[ ] {type} , new object[ ] {id} ); IList result = DoFind( session, qp, null, null, collection, owner, true ); this.CollectionPersister.Cache(id, collection, session); return result; }
            Hide
            mdoerfler Mike Doerfler added a comment -

            Look at PersistentCollection.EndRead()/SessionImpl.EndLoadingCollections(...) to see if the design still needs to be diff from hibernates. Solved the issue of multiple readers being opened with outerjoin loading and hybrid data reader.

            Show
            mdoerfler Mike Doerfler added a comment - Look at PersistentCollection.EndRead()/SessionImpl.EndLoadingCollections(...) to see if the design still needs to be diff from hibernates. Solved the issue of multiple readers being opened with outerjoin loading and hybrid data reader.
            Hide
            mdoerfler Mike Doerfler added a comment -

            Did alot of digging into how collections are being cached. In the middle of debugging, but it definitely is a problem as described.

            Show
            mdoerfler Mike Doerfler added a comment - Did alot of digging into how collections are being cached. In the middle of debugging, but it definitely is a problem as described.
            Hide
            mdoerfler Mike Doerfler added a comment -

            Code was committed to cvs - I believe it is fixed there by stepping through it during the test run.

            Need to find a better way than stepping through code to verify test is running - look at raising events from cache for hits, misses, etc...

            Show
            mdoerfler Mike Doerfler added a comment - Code was committed to cvs - I believe it is fixed there by stepping through it during the test run. Need to find a better way than stepping through code to verify test is running - look at raising events from cache for hits, misses, etc...
            Hide
            jammycakes James McKay added a comment -

            Okay, I've downloaded the latest sources from CVS and it seems to work fine now.

            There's one other related issue that I have noticed though. When I try to load a non-existent object using ISession.Get(), a subsequent request for the same object results in another round trip to the database. Would it be worth considering adding some kind of marker object to the cache in this case to flag that the item wasn't found?

            Show
            jammycakes James McKay added a comment - Okay, I've downloaded the latest sources from CVS and it seems to work fine now. There's one other related issue that I have noticed though. When I try to load a non-existent object using ISession.Get(), a subsequent request for the same object results in another round trip to the database. Would it be worth considering adding some kind of marker object to the cache in this case to flag that the item wasn't found?
            Hide
            mdoerfler Mike Doerfler added a comment -

            Hi James, this https://nhibernate.jira.com/browse/NH-160 describes what you've noticed.

            Collections are now loaded from cache when there.

            Mike

            Show
            mdoerfler Mike Doerfler added a comment - Hi James, this https://nhibernate.jira.com/browse/NH-160 describes what you've noticed. Collections are now loaded from cache when there. Mike
            Hide
            mdoerfler Mike Doerfler added a comment -

            0.7 was released

            Show
            mdoerfler Mike Doerfler added a comment - 0.7 was released

              People

              • Assignee:
                mdoerfler Mike Doerfler
                Reporter:
                jammycakes James McKay
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Who's Looking?