-->
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.  [ 10 posts ] 
Author Message
 Post subject: Problem with CompositeId+"key-many-to-one"+Caching
PostPosted: Wed Apr 25, 2007 5:00 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
Hello,

I'm using NHinernate 1.2RC2

I've found a problem when using an entity having a CompositeId having a property "key-many-to-one".

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

The problem is : if the entity goes in the cache, then the object is not retreive by the method ICache.Get(object key)
I'm using the basic HashTableCache.

Any idea ?
Thanks for your help


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 26, 2007 4:19 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
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>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 26, 2007 4:29 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
One more important information :
Category and Tariff instances are orginally loaded by a Query that goes in the cache.
If I disable "Query cache" the problem disapear....


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 26, 2007 8:18 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
Is it acceptable to change the implementation of EntityType as follow
because it correct the problem ?

public override sealed bool Equals(object x, object y)
{
return x.Equals(y);
// return x == y;
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 02, 2007 5:24 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
I manage to reproduce the problem in a small demo.
How can I send it to you ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 02, 2007 12:28 pm 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
The minimum mapping to reproduce the problem is :

<class name="Category">
<cache usage="read-write" region="Reference"/>
<id name="Id">
<generator class="increment"/>
</id>
<property name="Label"/>
</class>

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

<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" class ="Tariff">
<column name="CD_TARIF"/>
<column name ="CD_CAT_FRAIS"/>
</many-to-one>
</class>


With the following config :
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.JetDriver.JetDialect, NHibernate.JetDriver</property>
<property name="connection.driver_class">NHibernate.JetDriver.JetDriver, NHibernate.JetDriver</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.connection_string">Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\Data\AdminTariff.mdb</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>
<mapping assembly="Services" />
</session-factory>
</hibernate-configuration>


And the following steps :
- Session1 : load all Category instances in Second Level Cache
- Session2 : load all Tariff instances in Second Level Cache
- Session3 : load all TariffRule instances
Problem : a SQL order is perfomed to retreive Tariff instance linked to TariffRule, dispite the fact that the Tariff is in the Second Level Cache.


Please, any help ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 03, 2007 3:58 am 
Newbie

Joined: Sat May 14, 2005 2:17 pm
Posts: 18
I stumbled onto to the same problem and I just wait for an answer in this tread.

But what bothers me is that you get no response on a tread which is rather complete and detailed. I see this a lot on this forum. The product NHibernate is without any doubt very very good. But it lacks dedicated support in this forum. It is a shame because I see so many indications that NHibernate is lifting off. I see lectures, more questions in this forum, dedicated websites, ect. So there should be so kind of expert team to awnser all the questions. But that would rather hard to set up I guess.

Bas


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 03, 2007 4:53 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
Thanks Bas for your post. At least I feel less alone !
I agree with you that it is difficult to obtain any support on this forum... I think, if you want "real" support, you need to pay for it.
Don't you think NHibernate is lifting off also because of the delay announced by Microsoft on the availability of ADO Entity Framework (Mid2008 now) ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 03, 2007 5:05 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Submit a bug report please, I will look into how to fix this. And yes, if you want a guaranteed answer, you can buy support. We are all volunteers here, as far as the forum is concerned.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 03, 2007 5:52 am 
Beginner
Beginner

Joined: Fri Jan 19, 2007 10:45 am
Posts: 23
Thanks sergey for your answer.
I've open a bug report. ID is NH-995


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