具有二级缓存的NHibernate不会重新水化属性标记为insert =“false”update =“false”?

时间:2012-11-14 19:56:18

标签: nhibernate nhibernate-caches

在Nhibernate中实现二级缓存时遇到问题。我有一个映射如下的类:

<?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>

属性“ClientID”是Clients表中的外键,Client多对一属性使用它来查找关联的客户端对象。

当我添加一个新帐户时,我使用Session.Get从数据库中查找Client对象,并将其分配给我的Account对象的Client属性。在后台,当对象写入数据库时​​,这也会自动填充ClientID属性,并且ID正确地存储在数据库中。当我使用Session.Get通过ID从数据库中检索Account对象时,在检索对象时会正确填充所有字段。

但是,当我使用上面显示的设置实现二级缓存时,使用Session.Get检索Account对象时,不会填充ClientID属性,但会正确填充Client属性。有什么理由说这不能用于二级缓存吗?或者我在映射/配置中做错了什么?

现在我只是使用SysCache作为我的缓存提供程序,并且启用了查询和二级缓存。 Client类映射包含Accounts的相应一对多属性。

我喜欢在我的Account类上使用ClientID属性的便利性,这样我就可以在不使用Client属性的情况下读取它,并且它似乎在没有缓存的情况下正常工作。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我试图在本地重现你的情况。使用您的映射(与上面的代码段相同),我只能在UPDATE上获得不正确的行为。在这种情况下,ClientID被缓存,而Client引用更改时,ClientID保持不变。在其他情况下,缓存按预期工作。

解决方案是更改映射。以下建议的映射最适合像ClientID这样的只读属性。 (我也在使用这种方法。)

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

所以诀窍在于 formula 映射而不是Column(默认情况下没有提供)