-->
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: lazy fetching for one-to-one impossible??
PostPosted: Wed Apr 26, 2006 8:55 am 
Newbie

Joined: Wed Feb 25, 2004 10:43 am
Posts: 14
Hello,

I have 2 classes that are related through a one-to-one association, which is mapped to a foreign key. I am doing a query that retreives all instances of class A. When I look at the generated SQL, I see that for each A, another statement is issued to get the related B - leading to the infamous N+1 problem with extreme amounts of SQL being generated.

Since I do not need the A->B references in my particular case, I tried to modify the mapping such that the A->B reference would be resolved lazily. However, I seem to be unable to do away with the redundant SQL, no matter what I try. I have even found a section in the docs which seems to indicate that this is not possible at all, which I would find rather shocking, and, in my case, unacceptable.

Hibernate version: 3.1.2

mapping A:
one-to-one name="b" lazy="proxy" property-ref="a"

mapping B:
many-to-one name="a" column="a_id" update="false" unique="true" not-null="true"

Query:
from A a

thanks,
Christian


Top
 Profile  
 
 Post subject: Re: lazy fetching for one-to-one impossible??
PostPosted: Wed Apr 26, 2006 9:17 am 
Senior
Senior

Joined: Mon Aug 22, 2005 5:45 am
Posts: 146
Christian Sell wrote:
Hello,

I have 2 classes that are related through a one-to-one association, which is mapped to a foreign key. I am doing a query that retreives all instances of class A. When I look at the generated SQL, I see that for each A, another statement is issued to get the related B - leading to the infamous N+1 problem with extreme amounts of SQL being generated.

Since I do not need the A->B references in my particular case, I tried to modify the mapping such that the A->B reference would be resolved lazily. However, I seem to be unable to do away with the redundant SQL, no matter what I try. I have even found a section in the docs which seems to indicate that this is not possible at all, which I would find rather shocking, and, in my case, unacceptable.

Hibernate version: 3.1.2

mapping A:
one-to-one name="b" lazy="proxy" property-ref="a"

mapping B:
many-to-one name="a" column="a_id" update="false" unique="true" not-null="true"

Query:
from A a

thanks,
Christian


do you have constrained="false" ?

_________________
Please don't forget to give credit, if my posting helped to solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 9:41 am 
Newbie

Joined: Wed Feb 25, 2004 10:43 am
Posts: 14
I dont have the constrained= attribute set, which leads to a "false" default value. But even setting it to true does not change anything.

additionally, the association foreign key is located on the B side, not the A one - therefore, if I understand the "constrained" thing correctly, it would be plain wrong to set it to true.

I did read the statement in the docs that stated that a constrained="false" association could not be fetched lazily. If that statement applies to my situation, then I am pretty disappointed. My relational model and mapping seem perfectly normal to me, and there really is no alternative in my case.

The restriction hibernate imposes here does not seem reasonable to me at all.

Christian


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 11:18 am 
Expert
Expert

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 260
This is from reference documentation ( section 5.1.11 )

Quote:
lazy (optional - defaults to proxy): By default, single point associations are proxied. lazy="no-proxy" specifies that the property should be fetched lazily when the instance variable is first accessed (requires build-time bytecode instrumentation). lazy="false" specifies that the association will always be eagerly fetched. Note that if constrained="false", proxying is impossible and Hibernate will eager fetch the association!


Have you tried the option lazy="no-proxy"


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 11:42 am 
Newbie

Joined: Wed Feb 25, 2004 10:43 am
Posts: 14
I have tried that, too, although it is still unclear to me what that option means resp. what the difference between proxy/no-proxy is.

The last part of the quote from the docs you give says that for one-to-one associations that have constrained="false" (which is probably the default) lazy fetchning is impossible.
As I am loading the objects on the non-FK side (property-ref attribute), I cannot specify constrained=true. And even when I do, it doesnt change things.

I cannot believe that I am stuck here..


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 27, 2006 3:36 am 
Newbie

Joined: Wed Feb 25, 2004 10:43 am
Posts: 14
hmm.. does this really mean that hibernate does NOT do away with the infamous N+1 problem, which plagued persistence frameworks in the early days?


Top
 Profile  
 
 Post subject: Re: lazy fetching for one-to-one impossible??
PostPosted: Tue May 09, 2006 9:08 pm 
Newbie

Joined: Thu Sep 15, 2005 2:29 am
Posts: 3
I ran into the same problem here. There is n+1 selection. This is my configuration and resulting query:

In Document.hbm.xml:

<one-to-one name="estimate" class="Estimate"
constrained="true"
fetch="select"
property-ref="document"
lazy="proxy"/>


In Estimate.hbm.xml:

<many-to-one
name="document"
column="DOCUMENT_ID"
class="Document"
unique="true"
not-null="true"
>
</many-to-one>


findDocumentByDescription:
<query name = "findDocumentByDescription">
<![CDATA[
select d from Document d
where
d.description='One-2-One test'
]]>
</query>
generate queries like this:

Hibernate: select document0_.DOCUMENT_ID as DOCUMENT1_, document0_.TCN as TCN0_, document0_.CO_CD as CO3_0_, document0_.DESCRIPTION as DESCRIPT4_0_, document0_.DOC_STATUS_CODE as DOC5_0_, document0_.DOC_TYPE_CODE as DOC6_0_, document0_.DOC_DATE as DOC7_0_ from CY_DOCUMENT document0_ where document0_.DESCRIPTION='One-2-One test'
Hibernate: select estimate0_.ESTIMATE_ID as ESTIMATE1_0_, estimate0_.DOCUMENT_ID as DOCUMENT2_1_0_ from CY97212_ESTIMATE estimate0_ where estimate0_.DOCUMENT_ID=?
Hibernate: select estimate0_.ESTIMATE_ID as ESTIMATE1_0_, estimate0_.DOCUMENT_ID as DOCUMENT2_1_0_ from CY97212_ESTIMATE estimate0_ where estimate0_.DOCUMENT_ID=?
Hibernate: select estimate0_.ESTIMATE_ID as ESTIMATE1_0_, estimate0_.DOCUMENT_ID as DOCUMENT2_1_0_ from CY97212_ESTIMATE estimate0_ where estimate0_.DOCUMENT_ID=?
May 9, 2006 6:01:44 PM com.mitchell.hibernatetest.test.DocumentDAOTester testFindDocuments
INFO: doc id: 1473
May 9, 2006 6:01:44 PM com.mitchell.hibernatetest.test.DocumentDAOTester testFindDocuments
INFO: doc id: 1470
May 9, 2006 6:01:44 PM com.mitchell.hibernatetest.test.DocumentDAOTester testFindDocuments
INFO: doc id: 1476


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 09, 2006 9:10 pm 
Newbie

Joined: Thu Sep 15, 2005 2:29 am
Posts: 3
So in order not to get n+1 selection, I guess I have to choose back to use one-to-many here. At least I get the lazy initialization befenit.

Any recommendation?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 04, 2006 11:15 pm 
Newbie

Joined: Mon Mar 20, 2006 1:16 pm
Posts: 5
I believe I am having the same problem with 3.2 CR2. I can eliminate the N+1 queries if I change from bidirectional one-to-one to bidirectional one-to-many. Any better ideas?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 4:30 am 
Newbie

Joined: Wed Jul 05, 2006 8:49 am
Posts: 7
Location: Zurich
Have you tried <one-to-one ...... outer-join="false" />

This disables fetching using an outer join (even if proxying is disabled says the documentation).


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.