Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>Imagine 2 tables in a relational database, e.g. Person and Billing. There is a (non-mandatory) OneToOne association defined between these entities,</p> </blockquote> <p>Lazy fetching is conceptually not possible for non-mandatory OneToOne by default, Hibernate has to hit the database to know if the association is <code>null</code> or not. More details from this old wiki page:</p> <blockquote> <h3><a href="https://community.jboss.org/wiki/Someexplanationsonlazyloadingone-to-one" rel="nofollow noreferrer">Some explanations on lazy loading (one-to-one)</a></h3> <p>[...]</p> <p>Now consider our class B has one-to-one association to C</p> <pre><code>class B { private C cee; public C getCee() { return cee; } public void setCee(C cee) { this.cee = cee; } } class C { // Not important really } </code></pre> <p>Right after loading B, you may call <code>getCee()</code> to obtain C. But look, <code>getCee()</code> is a method of YOUR class and Hibernate has no control over it. Hibernate does not know when someone is going to call <code>getCee()</code>. That means Hibernate must put an appropriate value into "<code>cee</code>" property at the moment it loads B from database. If proxy is enabled for <code>C</code>, Hibernate can put a C-proxy object which is not loaded yet, but will be loaded when someone uses it. This gives lazy loading for <code>one-to-one</code>. </p> <p>But now imagine your <code>B</code> object may or may not have associated <code>C</code> (<code>constrained="false"</code>). What should <code>getCee()</code> return when specific <code>B</code> does not have <code>C</code>? Null. But remember, Hibernate must set correct value of "cee" at the moment it set <code>B</code> (because it does no know when someone will call <code>getCee()</code>). Proxy does not help here because proxy itself in already non-null object.</p> <p>So the resume: <strong>if your B->C mapping is mandatory (<code>constrained=true</code>), Hibernate will use proxy for C resulting in lazy initialization. But if you allow B without C, Hibernate just HAS TO check presence of C at the moment it loads B. But a SELECT to check presence is just inefficient because the same SELECT may not just check presence, but load entire object. So lazy loading goes away</strong>.</p> </blockquote> <p>So, not possible... by default. </p> <blockquote> <p>Is there a workaround for this potential performance disaster (other than not using a shared primary key at all)? Thank you for all your ideas.</p> </blockquote> <p>The problem is not the shared primary key, with or without shared primary key, you'll get it, the problem is the <strong>nullable</strong> OneToOne.</p> <p><strong>First option</strong>: use bytecode instrumentation (see references to the documentation below) and <em>no-proxy</em> fetching:</p> <pre><code>@OneToOne( fetch = FetchType.LAZY ) @org.hibernate.annotations.LazyToOne(org.hibernate.annotations.LazyToOneOption.NO_PROXY) </code></pre> <p><strong>Second option</strong>: Use a fake <code>ManyToOne(fetch=FetchType.LAZY)</code>. That's probably the most simple solution (and to my knowledge, the recommended one). But I didn't test this with a shared PK though.</p> <p><strong>Third option</strong>: Eager load the Billing using a <code>join fetch</code>.</p> <h3>Related question</h3> <ul> <li><a href="https://stackoverflow.com/questions/1444227/making-a-onetoone-relation-lazy">Making a OneToOne-relation lazy</a> </li> </ul> <h3>References</h3> <ul> <li>Hibernate Reference Guide <ul> <li><a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-proxies" rel="nofollow noreferrer">19.1.3. Single-ended association proxies</a></li> <li><a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-lazyproperties" rel="nofollow noreferrer">19.1.7. Using lazy property fetching</a> </li> </ul></li> <li>Old Hibernate FAQ <ul> <li><a href="http://web.archive.org/web/20071021233649/http://www.hibernate.org/117.html#A18" rel="nofollow noreferrer">How do I set up a 1-to-1 relationship as lazy?</a></li> </ul></li> <li>Hibernate Wiki <ul> <li><a href="https://community.jboss.org/wiki/Someexplanationsonlazyloadingone-to-one" rel="nofollow noreferrer">Some explanations on lazy loading (one-to-one)</a></li> </ul></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload