<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Moving the Curve &#187; hibernate</title>
	<atom:link href="http://www.stevideter.com/category/hibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stevideter.com</link>
	<description>Technology, code, and thoughts by Stevi Deter</description>
	<lastBuildDate>Fri, 16 Apr 2010 17:01:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>SaveOrUpdate versus Merge in Hibernate</title>
		<link>http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/</link>
		<comments>http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 22:19:33 +0000</pubDate>
		<dc:creator>stevi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[NonUniqueObjectException]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[saveOrUpdate]]></category>

		<guid isPermaLink="false">http://www.stevideter.com/?p=51</guid>
		<description><![CDATA[We all have those problems that we encounter just infrequently enough that when we see them again, we know we&#8217;ve solved this, but can&#8217;t remember how. The NonUniqueObjectException thrown when using Session.saveOrUpdate() in Hibernate is one of mine. I&#8217;ll be adding new functionality to a complex application. All my unit tests work fine. Then in [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>We all have those problems that we encounter just infrequently enough that when we see them again, we know we&#8217;ve solved this, but can&#8217;t remember how.</p>
<p>The NonUniqueObjectException thrown when using Session.saveOrUpdate() in Hibernate is one of mine. I&#8217;ll be adding new functionality to a complex application. All my unit tests work fine. Then in testing the UI, trying to save an object, I start getting an exception with the message &#8220;a different object with the same identifier value was already associated with the session.&#8221; Here&#8217;s some example code from <a href="http://www.amazon.com/gp/product/1932394885?ie=UTF8&#038;tag=movithecurv-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1932394885" title="Java Persistence with Hibernate">Java Persistence with Hibernate</a><img src="http://www.assoc-amazon.com/e/ir?t=movithecurv-20&#038;l=as2&#038;o=1&#038;a=1932394885" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Session session <span style="color: #339933;">=</span> sessionFactory1.<span style="color: #006633;">openSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Transaction tx <span style="color: #339933;">=</span> session.<span style="color: #006633;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Item item <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Item<span style="color: #009900;">&#41;</span> session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Item.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Long</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1234</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
tx.<span style="color: #006633;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
session.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// end of first session, item is detached</span>
&nbsp;
item.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// The database identity is &quot;1234&quot;</span>
item.<span style="color: #006633;">setDescription</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;my new description&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Session session2 <span style="color: #339933;">=</span> sessionFactory.<span style="color: #006633;">openSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Transaction tx2 <span style="color: #339933;">=</span> session2.<span style="color: #006633;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Item item2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Item<span style="color: #009900;">&#41;</span> session2.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Item.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Long</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1234</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
session2.<span style="color: #006633;">update</span><span style="color: #009900;">&#40;</span>item<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Throws NonUniqueObjectException</span>
tx2.<span style="color: #006633;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
session2.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>
To understand the cause of this exception, it&#8217;s important to understand detached objects and what happens when you call saveOrUpdate() (or just update()) on a detached object.</p>
<p>When we close an individual Hibernate Session, the persistent objects we are working with are detached. This means the data is still in the application&#8217;s memory, but Hibernate is no longer responsible for tracking changes to the objects.</p>
<p>If we then modify our persistent object and want to update it, we have to reattach the object. During that reattachment process, Hibernate will check to see if there are any other copies of the same object. If it finds any, it has to tell us it doesn&#8217;t know what the &#8220;real&#8221; copy is any more. Perhaps other changes were made to those other copies that we expect to be saved, but Hibernate doesn&#8217;t know about them, because it wasn&#8217;t managing them at the time.</p>
<p>Rather than save possibly bad data, Hibernate tells us about the problem via the NonUniqueObjectException.</p>
<p>So what are we to do? In Hibernate 3, we have merge() (in Hibernate 2, use saveOrUpdateCopy()). This method will force Hibernate to copy any changes from other detached instances onto the instance you want to save, and thus merges all the changes in memory before the save.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Session session <span style="color: #339933;">=</span> sessionFactory1.<span style="color: #006633;">openSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Transaction tx <span style="color: #339933;">=</span> session.<span style="color: #006633;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Item item <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Item<span style="color: #009900;">&#41;</span> session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Item.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Long</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1234</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
tx.<span style="color: #006633;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
session.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// end of first session, item is detached</span>
&nbsp;
item.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// The database identity is &quot;1234&quot;</span>
item.<span style="color: #006633;">setDescription</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;my new description&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Session session2 <span style="color: #339933;">=</span> sessionFactory.<span style="color: #006633;">openSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Transaction tx2 <span style="color: #339933;">=</span> session2.<span style="color: #006633;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Item item2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Item<span style="color: #009900;">&#41;</span> session2.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Item.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Long</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1234</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Item item3 <span style="color: #339933;">=</span> session2.<span style="color: #006633;">merge</span><span style="color: #009900;">&#40;</span>item<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Success!</span>
tx2.<span style="color: #006633;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
session2.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>
It&#8217;s important to note that merge returns a reference to the newly updated version of the instance. It isn&#8217;t reattaching item to the Session. If you test for instance equality (item == item3), you&#8217;ll find it returns false in this case. You will probably want to work with item3 from this point forward. </p>
<p>It&#8217;s also important to note that the Java Persistence API (JPA) doesn&#8217;t have a concept of detached and reattached objects, and uses EntityManager.persist() and EntityManager.merge(). </p>
<p>I&#8217;ve found in general that when using Hibernate, saveOrUpdate() is usually sufficient for my needs. I usually only need to use merge when I have objects that can have references to objects of the same type. Most recently, the cause of the exception was in the code validating that the reference wasn&#8217;t recursive. I was loading the same object into my session as part of the validation, causing the error.</p>
<p>Where have you encountered this problem? Did merge work for you or did you need another solution? Do you prefer to always use merge, or prefer to use it only as needed for specific cases?</p>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>
