-->
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.  [ 9 posts ] 
Author Message
 Post subject: No lazy loading with n:1 to non-primary-key
PostPosted: Tue Jul 31, 2007 7:36 am 
Newbie

Joined: Tue Jul 31, 2007 5:16 am
Posts: 9
3.2.2GA

Hi,
I use a simple legacy many-to-one relation from a foreign key (PFK) to a non primary-unique-key (PNo) with the attribute "property-ref". If I only select all addresses (see first code), hibernate generates an sql with join from address to person (fetch="join") or additional selects for each person (fetch="select"). So this is always eager loading and not with a proxy. I try a default relation direct from FK to a PK, this works fine with lazy load.
Why ist this handling different and how can I avoid the additional sql-effort with a non primary key?
We have and old informix db and i can't change this stupid schema.

Code:
Criteria crit = ifx.getSession().createCriteria(Address.class);
List<Address> lst = crit.list();


Code:
<class name="Person" >
      <id name="id" type="java.lang.Integer" column="id" />
      <property name="PNo" type="java.lang.Integer" not-null="true" unique="true" />
....
</class>


Code:
<class name="Address" >
...
      <many-to-one name="Person" class="Person" column="PFK" property-ref="PNo" />
...


my problem was discussed in some other topics. But nobody helps ;-(

http://forum.hibernate.org/viewtopic.php?t=958726&highlight=propertyref
http://forum.hibernate.org/viewtopic.php?t=968143&highlight=propertyref+eager
http://forum.hibernate.org/viewtopic.php?t=956866&highlight=propertyref+eager
http://forum.hibernate.org/viewtopic.php?t=935481&highlight=propertyref+redundant+joins

many thanx


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 8:29 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
According to Emmanuel of the hibernate team in this post of 2005:
http://forum.hibernate.org/viewtopic.php?p=2262590
Quote:
There is no way to guaranty object unicity in the session if proeprty-ref associations are not loaded.

So I think your stuck with it.

You say you can't change the schema but can you add new tables?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 8:39 am 
Beginner
Beginner

Joined: Mon Sep 12, 2005 3:27 am
Posts: 48
Hibernate must load the to-1 side, cause it else doesn't know, if this property is null or not.

As i remember, you can annotate your entity with *toOne(optional = false) in use-cases where the one-side is mandantory, to instrument hibernate to lazy load the *toOne-Associations.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 9:07 am 
Newbie

Joined: Tue Jul 31, 2007 5:16 am
Posts: 9
hi, thank you for your replies.
Okay, this is another topic for the problem. But I can't understand it. What is the difference between pk and an unique not-null key?
Emmanuel wrotes: "object unicity"? But a foreign-key without an associated primary-key is also possible.
Our legacy database includes 250 tables.
I dont wont create more tables for hibernate-lazy load ;-)
This issue is a small problem for the two tables in my test above but in a extreme case hibernate loads our whole database. Address->Person->Company-> and so on.


Top
 Profile  
 
 Post subject: Is there any solution?
PostPosted: Thu Aug 02, 2007 3:14 am 
Newbie

Joined: Tue Jul 31, 2007 5:16 am
Posts: 9
Is there nobody who can help in this issue???

I read a lot of stuff, so I understand that hibernate need the primary id for the proxy instance.
If I use property-ref, the pk in the referenced object ist by nature not equal to the fk, so the pk must be loaded extra for the proxy.

I think the problem is, that if hibernate read the pk than hibernate read always the whole entity.
If hibernate read the entity it resolve all associations for this entity und so we run into a recursive issue, cause this entity includes some other Foreign-keys to non primary-keys and so on.
Is this bug?

In my case I read only one address and get about hundred sqls or a joind-sql from germany to america.

thank you for reply


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 02, 2007 7:06 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Sorry - error in my test case - this DOESN'T help.


Quote:
As a workaround you could add join tables between some (or all) of the classes that use a property-ref to reference another entity directly. The join tables can continue using property-ref but don't get eagerly loaded. Hibernate will manage them and your code won't need to change (apart from taking into account that person is now lazy loaded). Just a few join tables in the right places could be enough to pervent you loading the entire database.

<!-- using join table -->
<join table="propertyref_address_person" optional="true">
<key column="addressId" unique="true"/>
<many-to-one name="person"
column="personId"
not-null="true" property-ref="PNo" />
</join>

<!-- old way - direct reference causes eager loading
<many-to-one name="Person"
column="PFK"
property-ref="PNo"
not-null="true"
/>
-->


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 02, 2007 8:37 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
I don't think you can configure your way out of this. I'm looking at the source code for 3.2.4sp1 - when collections are loaded the EntityType class does this:
Code:
         if ( isReferenceToPrimaryKey() ) {
            return resolveIdentifier( (Serializable) value, session );
         }
         else {
            return loadByUniqueKey( getAssociatedEntityName(), uniqueKeyPropertyName, value, session );
         }


If your collection referes to the primary key of the other entity you get resolveIdentifier. When you use property-ref loadByUniqueKey gets called.

In resolveIdentifier it handles the proxying of the collection. Not so in loadByUniqueKey. In fact the first line of this method says:
//TODO: implement caching?! proxies?!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 03, 2007 4:01 am 
Newbie

Joined: Tue Jul 31, 2007 5:16 am
Posts: 9
Hi mike,
yes i think der is a possible solution if only the referenced pk-id will be loaded from the db and create a proxy with it. But I dont have an overview with the hibernate internal code.
Hope the hibernate team can help...

Is there another Workaround?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 5:32 am 
Newbie

Joined: Tue Jul 31, 2007 5:16 am
Posts: 9
I did an entry to JIRA
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2766


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