-->
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.  [ 2 posts ] 
Author Message
 Post subject: second level cache collection object is not evicted
PostPosted: Fri Mar 31, 2006 5:55 pm 
Newbie

Joined: Fri Jan 20, 2006 12:47 pm
Posts: 16
Location: Ottawa, On
Hi All,

I have a collection of objects in a class which I cascade using save-update. The collection also has a read-write cache associated with it.

I DO NOT cascade deletes via the collection as due to specific requirements in my app If an object is being referenced as a foreign key in the database I have some specific logic to inactivate it, but it still is removed from the collection.

Here is where it gets weird, If I instantiate an instance of the class (Lpcorganization), load the Positions collection (which caches the collection) and do a separate delete at that point, I can evict the Positions collection from the second level cache and it works fine.

But ... if, I instantiate an instance of Lpcorganization, load the Positions collection, ADD a new postion to the collection (which is successful) and then perform the delete, after the eviction of the collection from the second level cache I get a lazy load exception (pasted below) saying that the object with the id that I deleted is no longer in the database.

So, for some reason if I add objects to the collection, either the EvictCollection call on the cache does not properly evict the collection, or a reference to the colection has been added to the cahce in a region which I am unaware of.

One final item, as a test, if I set the cascade on the collection to all-delete-orphan, and do the delete via the collection, it works fine before and after an add ...... the cache updates itself correctly an on the next lazy load of the collection the deleted item has been removed.

There seem to be a few posting on the cache and evicting, are there other cache regions created for collections other than the classname + property one (rolename in the source) which I am not aware of?

Any help on this would really be appreciated ... as it is, I can use the cache for read-only collections and it seems for collections with cascade all-delete-orphan, but I cannot have a collection which references related objects which are maintained in a different part of the system ....

I have alot of data which falls in this last category, it is maintained elsewhere in the system and in all probability will not be updated often, but when it is, I obviouusly have to be able to force any cached references to that data to be destroyed and re-queried.

Hibernate version:
1.0.2

Mapping documents:

Class which contains the collection

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo" default-cascade="save-update" auto-import="false" default-access="field.pascalcase-m-underscore">
<class name="xwave.NMR.DL.DTO.Lpcorganization, DataAccess" table="LPC_ORGANIZATIONS" >
<cache usage="read-write"/>
<id name="Id" type="Decimal" column="LPC_ORG_ID" unsaved-value="0">
<generator class="identity" />
</id>

<timestamp name="LastUpdated" column="LAST_UPDATED"/>
<property name="Active" column="ACTIVE" type="Boolean" />

<property name="Order" column="LPC_ORGANIZATION_ORDER" type="Int16" />

<property name="en" column="VALUE_EN_CA" type="String" />
<property name="fr" column="VALUE_FR_CA" type="String" />
<property name="OrganizationType" column="ORG_TYPE_ID" type="Decimal" />

<bag name="LPCOrganizationalGroups" table="ORGANIZATION_GROUPS" lazy="true" cascade="all-delete-orphan">
<cache usage="read-write"/>
<key column="ORGANIZATION_ID"/>
<one-to-many class="xwave.NMR.DL.DTO.Organizationgroup, DataAccess"/>
</bag>

<bag name="Positions" table="LPC_ORGANIZATION_POSITIONS" lazy="true" cascade="save-update">
<cache usage="read-write"/>
<key column="LPC_ORG_ID" />
<one-to-many class="xwave.NMR.DL.DTO.LPCOrganizationPosition, DataAccess" />
</bag>
</class>
</hibernate-mapping>

LPCOrganizationPosition

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" schema="dbo" default-cascade="save-update" auto-import="false" default-access="field.pascalcase-m-underscore">
<class name="xwave.NMR.DL.DTO.LPCOrganizationPosition, DataAccess" table="LPC_ORGANIZATION_POSITIONS">
<cache usage="read-write"/>
<id name="Id" column="LPC_ORG_POSITION_ID" type="Decimal">
<generator class="identity"/>
</id>

<timestamp name="LastUpdated" column="LAST_UPDATED"/>

<many-to-one name="LPCOrganization" column="LPC_ORG_ID" class="xwave.NMR.DL.DTO.Lpcorganization, DataAccess"/>

<property name="Active" column="ACTIVE" type="Boolean" />
<property name="Directory" column="DIRECTORY" type="Int16" />
<many-to-one name="Positiontitle" column="POSITION_TITLE_ID" class="xwave.NMR.DL.DTO.Positiontitle, DataAccess" cascade="none"/>
<property name="Singleposition" column="SINGLE_POSITION" type="Boolean" />
<property name="en" column="DESCRIPTION_EN_CA" type="String" not-null="true"/>
<property name="fr" column="DESCRIPTION_FR_CA" type="String" not-null="true"/>

<bag name="PositionsHeld" lazy="true" table="POSITION_HELD" cascade="none" where="held_to is null">
<!--<cache usage="read-write"/>-->
<key column="LPC_ORG_POSITION_ID"/>
<one-to-many class="xwave.NMR.DL.DTO.PositionHeld, DataAccess"/>
</bag>

<bag name="AllPositionsHeld" lazy="true" table="POSITION_HELD" cascade="none">
<cache usage="read-write"/>
<key column="LPC_ORG_POSITION_ID"/>
<one-to-many class="xwave.NMR.DL.DTO.PositionHeld, DataAccess"/>
</bag>

<bag name="OrganizationalGroupPositions" lazy="true" table="ORGANIZATIONAL_GROUP_POSITIONS" cascade="none">
<cache usage="read-write"/>
<key column="LPC_ORG_POSITION_ID"/>
<one-to-many class="xwave.NMR.DL.DTO.OrgGroupPosition, DataAccess"/>
</bag>
</class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

test Code which works:

Lpcorganization lpco = (Lpcorganization) session.Get(typeof(Lpcorganization),(decimal) 1);

//obviously this position must be in the collection

LPCOrganizationPosition lpcop = (LPCOrganizationPosition) session.Get(typeof(LPCOrganizationPosition),(decimal) 1);

ITransaction trans = session.BeginTransaction();

session.Delete(lpcop);

trans.Commit();

sessionFactory.EvictCollection("xwave.NMR.DL.DTO.Lpcorganization.Positions");


//this lazy load of the collection will work
foreach (LPCOrganizationPosition pos in lpco.Positions){
}


test code which doesn't work:

Lpcorganization lpco = (Lpcorganization) session.Get(typeof(Lpcorganization),(decimal) 1);

/////////////////// this is the new part ///////////////
LPCOrganizationPosition lpcop = new LPCOrganizationPosition();

//set some of the properties
lpcop.en="hi";
lpcop.fr="fr";

lpco.Positions.Add(lpcop);

ITransaction trans = session.BeginTransaction();

session.SaveOrUpdate(lpco);

trans.Commit();

//////////////// end of new part ///////////////////////////////


ITransaction trans = session.BeginTransaction();

session.Delete(lpcop);

trans.Commit();

sessionFactory.EvictCollection("xwave.NMR.DL.DTO.Lpcorganization.Positions");


//now, the lazy load throws the exception below .....
foreach (LPCOrganizationPosition pos in lpco.Positions){
}


Full stack trace of any exception that occurs:

2006-03-31 16:49:57,661 [2900] ERROR xwave.NMR.Web.UI.PageFramework.NMRPageBaseHelper [(null)] <(null)> - NMR Page Error Occurred:
NHibernate.LazyInitializationException: Failed to lazily initialize a collection ---> NHibernate.UnresolvableObjectException: No row with the given identifier exists: 4418, of class: xwave.NMR.DL.DTO.LPCOrganizationPosition
at NHibernate.UnresolvableObjectException.ThrowIfNull(Object o, Object id, Type clazz)
at NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id)
at NHibernate.Type.ManyToOneType.ResolveIdentifier(Object id, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner)
at NHibernate.Collection.Bag.InitializeFromCache(ICollectionPersister persister, Object disassembled, Object owner)
at NHibernate.Impl.SessionImpl.InitializeCollectionFromCache(Object id, Object owner, ICollectionPersister persister, PersistentCollection collection)
at NHibernate.Impl.SessionImpl.InitializeCollection(PersistentCollection collection, Boolean writing)
at NHibernate.Collection.PersistentCollection.Initialize(Boolean writing)
--- End of inner exception stack trace ---
at NHibernate.Collection.PersistentCollection.Initialize(Boolean writing)
at NHibernate.Collection.PersistentCollection.Read()
at NHibernate.Collection.Bag.GetEnumerator()
at xwave.NMR.Web.Maintain.PositionDefinitions.Listing.LoadPositionData() in c:\inetpub\wwwroot\nmrwebapp\maintain\position_definitions\listing.aspx.cs:line 127
at xwave.NMR.Web.Maintain.PositionDefinitions.Listing.OnColumnButton_Click(Object sender, DataGridCommandEventArgs e) in c:\inetpub\wwwroot\nmrwebapp\maintain\position_definitions\listing.aspx.cs:line 155
at System.Web.UI.WebControls.DataGrid.OnItemCommand(DataGridCommandEventArgs e)
at System.Web.UI.WebControls.DataGrid.OnBubbleEvent(Object source, EventArgs e)
at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
at System.Web.UI.WebControls.DataGridItem.OnBubbleEvent(Object source, EventArgs e)
at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
at System.Web.UI.WebControls.ImageButton.OnCommand(CommandEventArgs e)
at System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain()


Name and version of the database you are using:

SQL Server 2000 sp4


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 12:05 pm 
Newbie

Joined: Fri Jan 20, 2006 12:47 pm
Posts: 16
Location: Ottawa, On
Sorry the initial post was so long ... and convoluted!

In a nutshell I am getting the error described above after the following operations:

Lazily load the collection (performs db lookup, caches collection)

Add a new object to collection via cascades (updates cache, all OK)

delete one of the objects which is referenced by the collection, but not using cascades, delete is done separately

Evict collection from cache

lazy load collection again (for some reason object which was deleted is still picked up from cache .... so it is not evicted)


Again, if I change this scenario to either do the delete via the collection and cascades, everything is fine on the second lazy load i.e the collection updates the second level cache correctly.

The more puzzling case is if I leave out the add a new object from the steps above, the evict seems to work and the object I deleted elsewhere in the system is no longer in the cached version of the colection

so, why does doing an add via cascades make a subsequent evictCollection call not actually evict the collection from the cache?

Has anyone else had this problem? I have found some posts in the Hibernate forum pertaining to old 2.1.x versions of HIbernate which seemed to detail very similar problems ... is it possible that there was a bug in the older Hibernate versions which was later fixed, but has been propogated to NHibernate in the initial port from the older Hibernate code base?

Any insight would really be appreciated!


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