<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: JPA implementation patterns: Bidirectional associations vs. lazy loading</title>
	<atom:link href="http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/</link>
	<description></description>
	<lastBuildDate>Thu, 18 Mar 2010 13:27:36 +0100</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Vincent Partington</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92993</link>
		<dc:creator>Vincent Partington</dc:creator>
		<pubDate>Sat, 31 Oct 2009 09:19:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92993</guid>
		<description>&lt;strong&gt;@Bruno:&lt;/strong&gt; I wholeheartedly  agree with your rule of thumb. It is a lot harder to get the performance of large collections mapped as one-to-many relations right than if you were to retrieve them using a query (solution #1). So if the set becomes large, it is safer to go the explicit-query route.

One problem exists though: because it is so easy to set up @OneToMany associations and it makes traversing the object graph easier, you are likely to end up with @OneToMany associations where you don&#039;t want them later on. In fact, what might be small set of data when you start a project, might end up becoming a large set when actual data flows through the program. So the safest thing of all would be to avoid @OneToMany associations altogether. Hmm...</description>
		<content:encoded><![CDATA[<p><strong>@Bruno:</strong> I wholeheartedly  agree with your rule of thumb. It is a lot harder to get the performance of large collections mapped as one-to-many relations right than if you were to retrieve them using a query (solution #1). So if the set becomes large, it is safer to go the explicit-query route.</p>
<p>One problem exists though: because it is so easy to set up @OneToMany associations and it makes traversing the object graph easier, you are likely to end up with @OneToMany associations where you don&#8217;t want them later on. In fact, what might be small set of data when you start a project, might end up becoming a large set when actual data flows through the program. So the safest thing of all would be to avoid @OneToMany associations altogether. Hmm&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bruno</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92972</link>
		<dc:creator>Bruno</dc:creator>
		<pubDate>Wed, 28 Oct 2009 17:55:11 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92972</guid>
		<description>I was very excited to find this post because I have not found this issue discussed thoroughly elsewhere.  The issue of large collections and inadvertent lazy-loading is one that has plagued me for years.  In fact, we have been using TopLink and invented a framework to accomplish exactly the &quot;exercise for the reader&quot; you put forth.  But this framework imposes a fair amount of boilerplate code into the entity classes and I&#039;ve been fighting with bugs in the implementation for years (only some of which I introduced myself :-)).

After all of this time, I have finally come to the simple conclusion that using one-to-many relationships for large collections is a just a bad idea.  Even if you are to get around the issues with lazy-loading, you still face the problem of the memory usage for the collection.  We use EclipseLink&#039;s &quot;SoftWeak&quot; caching strategy in general.  But when one object holds a collection to hundreds or thousands of other entities that otherwise have only a weak reference, garbage collection is severely hampered.  I basically draw the line at around 100 objects.  Any relationship that would involve more than 100 objects is not a candidate for a collection mapping.  This is not a hard and fast rule, but I have found that the cost of the extra DAO and service layer coding outweighs the hassles of dealing with these performance issues.</description>
		<content:encoded><![CDATA[<p>I was very excited to find this post because I have not found this issue discussed thoroughly elsewhere.  The issue of large collections and inadvertent lazy-loading is one that has plagued me for years.  In fact, we have been using TopLink and invented a framework to accomplish exactly the &#8220;exercise for the reader&#8221; you put forth.  But this framework imposes a fair amount of boilerplate code into the entity classes and I&#8217;ve been fighting with bugs in the implementation for years (only some of which I introduced myself <img src='http://blog.xebia.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<p>After all of this time, I have finally come to the simple conclusion that using one-to-many relationships for large collections is a just a bad idea.  Even if you are to get around the issues with lazy-loading, you still face the problem of the memory usage for the collection.  We use EclipseLink&#8217;s &#8220;SoftWeak&#8221; caching strategy in general.  But when one object holds a collection to hundreds or thousands of other entities that otherwise have only a weak reference, garbage collection is severely hampered.  I basically draw the line at around 100 objects.  Any relationship that would involve more than 100 objects is not a candidate for a collection mapping.  This is not a hard and fast rule, but I have found that the cost of the extra DAO and service layer coding outweighs the hassles of dealing with these performance issues.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vincent Partington</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92343</link>
		<dc:creator>Vincent Partington</dc:creator>
		<pubDate>Mon, 24 Aug 2009 19:09:18 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92343</guid>
		<description>&lt;strong&gt;@M:&lt;/strong&gt; Are you saying that the child table only has two columns? The first a foreign key to the parent and the second column the string value? And the primary key is the combination of that foreign key and the string value?

In that case one way to do it is to define the child as a separate entity with a composite primary key defined with the &lt;a href=&quot;http://java.sun.com/javaee/5/docs/api/javax/persistence/IdClass.html&quot; rel=&quot;nofollow&quot;&gt;&lt;tt&gt;@IdClass&lt;/tt&gt;&lt;/a&gt; annotation.

Is that what you are looking for? If not, please post the definition of your schema.</description>
		<content:encoded><![CDATA[<p><strong>@M:</strong> Are you saying that the child table only has two columns? The first a foreign key to the parent and the second column the string value? And the primary key is the combination of that foreign key and the string value?</p>
<p>In that case one way to do it is to define the child as a separate entity with a composite primary key defined with the <a href="http://java.sun.com/javaee/5/docs/api/javax/persistence/IdClass.html" rel="nofollow"><tt>@IdClass</tt></a> annotation.</p>
<p>Is that what you are looking for? If not, please post the definition of your schema.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: M</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92307</link>
		<dc:creator>M</dc:creator>
		<pubDate>Tue, 18 Aug 2009 20:29:01 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92307</guid>
		<description>Hello,

As I am new to jpa, please forgive the simplicity of the question. I have the following problem:

How can I read a collection of strings from a child table that references the parent table by a FK ? The database is legacy and I can not change it. This seems likes such a basic operation and it frustrates me that I do not know how to do it in JPA. 

Thank You,
MPK</description>
		<content:encoded><![CDATA[<p>Hello,</p>
<p>As I am new to jpa, please forgive the simplicity of the question. I have the following problem:</p>
<p>How can I read a collection of strings from a child table that references the parent table by a FK ? The database is legacy and I can not change it. This seems likes such a basic operation and it frustrates me that I do not know how to do it in JPA. </p>
<p>Thank You,<br />
MPK</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vincent Partington</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92157</link>
		<dc:creator>Vincent Partington</dc:creator>
		<pubDate>Fri, 24 Jul 2009 11:21:55 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92157</guid>
		<description>&lt;strong&gt;@Andrew:&lt;/strong&gt; Interesting idea to abstract the queued operation into a separate set implementation.

One remark about the last paragraph where you mention that the queued operations need to be propagated to the underlying set before the transaction is committed: this is not necessary when the set is not the owning side of a bidirectional relation (i.e.. when the set has the mappedBy field set on the &lt;tt&gt;@OneToMany&lt;/tt&gt; annotation). And in most cases that is so.

In any case, you&#039;d rather not do this last-minute propagation because initializating the set is expensive (the reason we are bothering with this pattern anyway).</description>
		<content:encoded><![CDATA[<p><strong>@Andrew:</strong> Interesting idea to abstract the queued operation into a separate set implementation.</p>
<p>One remark about the last paragraph where you mention that the queued operations need to be propagated to the underlying set before the transaction is committed: this is not necessary when the set is not the owning side of a bidirectional relation (i.e.. when the set has the mappedBy field set on the <tt>@OneToMany</tt> annotation). And in most cases that is so.</p>
<p>In any case, you&#8217;d rather not do this last-minute propagation because initializating the set is expensive (the reason we are bothering with this pattern anyway).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Andrew Phillips</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92155</link>
		<dc:creator>Andrew Phillips</dc:creator>
		<pubDate>Fri, 24 Jul 2009 08:33:14 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92155</guid>
		<description>A thought on 3 (&quot;postponing operations on the collection&quot;): wouldn&#039;t you want to move the &quot;interception&quot; into the collection itself? The suggestion is essentially proposal for how to process collection operations, so you&#039;d presumably want that in a collection class, rather than in the DAO itself.

But there are some gotchas, like ensuring any decorating collections are created only after the field injection of the ORM-managed fields has taken place. I guess &lt;tt&gt;@PostConstruct&lt;/tt&gt; could be used for that, but that’s a bit ugly. Or you could use double checked locking.

So something like

&lt;pre lang=&quot;java&quot;&gt;
class Entity {
  Collection persistedCollection;
  transient Collection lateLoadingPersistedCollection;

  @PostConstruct
  void createLateLoadingCollections() {
    lateLoadingPersistedCollection = new LateLoadingCollection(persistedCollection);
  }

  Collection getPersistedCollection() {
    return lateLoadingPersistedCollection;
  }

}
&lt;/pre&gt;

or

&lt;pre lang=&quot;java&quot;&gt;
class Entity {
  Collection persistedCollection;

  // let&#039;s pretend closures made it to Java 7
  transient LazyField lateLoadingPersistedCollection =
    new LazyField({ new LateLoadingCollection(persistedCollection) });

  Collection getPersistedCollection() {
    assert persistedCollection != null;
    return lateLoadingPersistedCollection.get();
  }

}
&lt;/pre&gt;

where &lt;tt&gt;LazyField&lt;/tt&gt; is just some wrapper around some double-checked locking lazy instantiation code.

Because both examples rely on returning the decorated collection from the getter, this presumably wouldn&#039;t work with property access, by the way (but I guess that &lt;a href=&quot;http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/&quot; rel=&quot;nofollow&quot;&gt;wouldn&#039;t bother you&lt;/a&gt;).

The &lt;tt&gt;LateLoadingCollection&lt;/tt&gt; itself would just be a decorator around the real, ORM-managed collection that would intercept the add and remove methods (storing the values in a queue or whatever) and would simply merge and then delegate to the underlying set in all other cases, which would result in a load whenever e.g. the iterator was called.

A key question here would be whether there is some guarantee that &lt;tt&gt;get&lt;/tt&gt; (or any of the other methods that would result in a merge of any queued changes) would be called when an entity is persisted. Otherwise, changes to the underlying &lt;tt&gt;persistedCollection&lt;/tt&gt; might not be saved, of course...</description>
		<content:encoded><![CDATA[<p>A thought on 3 (&#8221;postponing operations on the collection&#8221;): wouldn&#8217;t you want to move the &#8220;interception&#8221; into the collection itself? The suggestion is essentially proposal for how to process collection operations, so you&#8217;d presumably want that in a collection class, rather than in the DAO itself.</p>
<p>But there are some gotchas, like ensuring any decorating collections are created only after the field injection of the ORM-managed fields has taken place. I guess <tt>@PostConstruct</tt> could be used for that, but that’s a bit ugly. Or you could use double checked locking.</p>
<p>So something like</p>
<pre lang="java">
class Entity {
  Collection persistedCollection;
  transient Collection lateLoadingPersistedCollection;

  @PostConstruct
  void createLateLoadingCollections() {
    lateLoadingPersistedCollection = new LateLoadingCollection(persistedCollection);
  }

  Collection getPersistedCollection() {
    return lateLoadingPersistedCollection;
  }

}
</pre>
<p>or</p>
<pre lang="java">
class Entity {
  Collection persistedCollection;

  // let's pretend closures made it to Java 7
  transient LazyField lateLoadingPersistedCollection =
    new LazyField({ new LateLoadingCollection(persistedCollection) });

  Collection getPersistedCollection() {
    assert persistedCollection != null;
    return lateLoadingPersistedCollection.get();
  }

}
</pre>
<p>where <tt>LazyField</tt> is just some wrapper around some double-checked locking lazy instantiation code.</p>
<p>Because both examples rely on returning the decorated collection from the getter, this presumably wouldn&#8217;t work with property access, by the way (but I guess that <a href="http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/" rel="nofollow">wouldn&#8217;t bother you</a>).</p>
<p>The <tt>LateLoadingCollection</tt> itself would just be a decorator around the real, ORM-managed collection that would intercept the add and remove methods (storing the values in a queue or whatever) and would simply merge and then delegate to the underlying set in all other cases, which would result in a load whenever e.g. the iterator was called.</p>
<p>A key question here would be whether there is some guarantee that <tt>get</tt> (or any of the other methods that would result in a merge of any queued changes) would be called when an entity is persisted. Otherwise, changes to the underlying <tt>persistedCollection</tt> might not be saved, of course&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JPA Implementation Patterns &#171; Fernando Franzini Java Blog</title>
		<link>http://blog.xebia.com/2009/05/25/jpa-implementation-patterns-bidirectional-associations-vs-lazy-loading/comment-page-1/#comment-92099</link>
		<dc:creator>JPA Implementation Patterns &#171; Fernando Franzini Java Blog</dc:creator>
		<pubDate>Thu, 16 Jul 2009 12:14:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.xebia.com/?p=1772#comment-92099</guid>
		<description>[...] Bidirectional associations vs. lazy loading [...]</description>
		<content:encoded><![CDATA[<p>[...] Bidirectional associations vs. lazy loading [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>
