Hello, I had a closer look at the problem...
Category is an entity that goes in the second level cache and is retreived by a session1.
Tariff is an entity that goes in the second level cache and is retreived by a session2.
Tariff has a composite-id base on 1 string + 1 Category (using key-many-to-one)
TariffRule has a many-to-one relation with Tariff and is retreived by a session3.
Problem : when a TariffRule is retreived, NHibernate try to look in the second level cache if the linked Tariff is present.
To do that it builds a CacheKey based on 1 string + 1 Category.
The entry in the cache could not be found because the following tests (in red) are not true:
(CacheKey.cs)
public override bool Equals(Object other)
{
if (!(other is CacheKey)) return false;
CacheKey that = (CacheKey) other;
return type.Equals(key, that.key) && entityOrRoleName.Equals(that.entityOrRoleName);
}
(ComponentType.cs)
public override bool Equals(object x, object y)
{
if (x == y)
{
return true;
}
if (x == null || y == null)
{
return false;
}
for (int i = 0; i < propertySpan; i++)
{
// not true for the second property correponding to the Category part of the composite key if (!propertyTypes[i].Equals(getters[i].Get(x), getters[i].Get(y))) {
return false;
}
}
return true;
}
(EntityType.cs)
public override sealed bool Equals(object x, object y)
{
return x == y;
}
In this last test : x and y are Category instances.
x.Equals(y) =>true (because an overrided method Equals exists on Category)
x == y => false
I spent quite a long time to analyse this problem, and I really appreciate any help...
Thanks a lot.
<class name="Tariff" table="CATALOGUE_GENERAL">
<cache usage="read-write" region="Reference"/>
<composite-id name="CompId" class="CompositeId">
<key-property name="Id" column="ID_CAT_ELEMENT"/>
<key-many-to-one name="Category" class="Category" column="CD_CAT_FRAIS"/>
</composite-id>
<class name="TariffRule" table="REGLES_FRAIS">
<id name="Id" type="Int32">
<generator class="increment"/>
</id>
<version name="Version" column="Version"/>
<many-to-one name="Tariff">
<column name="CD_TARIF"/>
<column name ="CD_CAT_FRAIS"/>
</many-to-one>
</class>
|