NHibernate with Second Level Cache Not Rehydrating Properties Marked insert="false" update="false"?

StackOverflow https://stackoverflow.com/questions/13386312

  •  29-11-2021
  •  | 
  •  

Domanda

Having trouble with implementing second level cache in Nhibernate. I have a class mapped as follows:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" namespace="Data">
   <class name="Account" table="Accounts" lazy="false">
     <cache region="Standard" usage="read-write" include="all"/>
     <id column="ID" name="ID">
       <generator class="assigned" />
     </id>
     <version name="VersionStamp" column="VersionStamp" type="integer" unsaved-value="0" />
     <property name="Name" not-null="true" />
     <property name="Type" not-null="true" />
     <property name="ClientID" not-null="true" insert="false" update="false" />
     <property name="DateCreated" not-null="true" type="UtcDateTime" />
     <property name="LastUpdatedDate" not-null="true" type="UtcDateTime" />
     <property name="IsActive" not-null="true" />
     <many-to-one name="Client" class="Client" column="ClientID" not-found="exception" not-null="true" />
   </class>
 </hibernate-mapping>

The property "ClientID" is a foreign key into the Clients table and the Client many-to-one property uses it to look up the associated client object.

When I add a new Account, I look up the Client object from the database with a Session.Get and assign it to my Account object's Client property. Behind the scenes, this also automatically populates the ClientID property when the object is written to the database, and the ID is correctly stored in the database. When I retrieve the Account object from the database by ID using Session.Get, all the fields are populated correctly when the object is retrieved.

However, when I implement the second level cache using the settings shown above, the ClientID property is NOT populated when the Account object is retrieved using Session.Get, but the Client property is populated correctly. Is there some reason why this will not work with second level cache? Or have I done something wrong in my mapping/configuration?

For now I am just using SysCache as my caching provider, and both query and second level cache are turned on. The Client class mapping contains a corresponding one-to-many property for the Accounts.

I like the convenience of having the ClientID property on my Account class, so that I can read it without using the Client property, and it seems to work fine without caching.

Thanks for any help.

Rich

È stato utile?

Soluzione

I tried to reproduce your situation locally. With your mapping (used the same as the snippet above) I was able to get incorrect behaviour only on UPDATE. In that case, the ClientID was cached, and while the Client reference was changed, the ClientID remained unchanged. In other cases caching was working as expected.

The solution is to change the mapping. The below suggested mapping is the most suitable for read-only properties like ClientID. (I am using that approach as well).

<property name="ClientID" formula="[ClientId]" 
        not-null="true" insert="false" update="false" />

So the trick is in the formula mapping instead of Column (the default when none is provided)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top