<?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>Java crumbs &#187; order</title>
	<atom:link href="http://blog.krecan.net/tag/order/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.krecan.net</link>
	<description>Short remarks from Java world</description>
	<lastBuildDate>Tue, 27 Jul 2010 13:56:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Flushing Hibernate</title>
		<link>http://blog.krecan.net/2008/01/05/flushing-hibernate/</link>
		<comments>http://blog.krecan.net/2008/01/05/flushing-hibernate/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 12:58:27 +0000</pubDate>
		<dc:creator>Lukáš Křečan</dc:creator>
				<category><![CDATA[Articles in English]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[DML]]></category>
		<category><![CDATA[flush]]></category>
		<category><![CDATA[order]]></category>

		<guid isPermaLink="false">http://blog.krecan.net/2008/01/05/flushing-hibernate/</guid>
		<description><![CDATA[Today I am going to write about Hibernate flushing. Do not worry, I am not going to flush Hibernate to the toilet. I will write about the way, how Hibernate propagates changes to the database. 
When you are modifying data using Hibernate, you have to keep in mind that Hibernate uses so called write-behind. It [...]]]></description>
			<content:encoded><![CDATA[<p>Today I am going to write about Hibernate flushing. Do not worry, I am not going to flush Hibernate to the toilet. I will write about the way, how Hibernate propagates changes to the database. </p>
<p>When you are modifying data using Hibernate, you have to keep in mind that Hibernate uses so called write-behind. It means that Hibernate propagates changes to the database as late as possible. By default this propagation (flushing) happens at the following times</p>
<ul>
<li>when transaction is committed</li>
<li>before query is executed</li>
<li>when  flush() method is called explicitly</li>
</ul>
<p>Usually such behavior is a good thing. It enables Hibernate to optimize data modifications and allows grouping many changes to one big batch update. But sometimes you can encounter some interesting issues. Lets show it on some example. Lets have following entity class:</p>
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
<tr>
  <!-- start source code --></p>
<td nowrap="nowrap" valign="top" align="left">
    <code><br />
<font color="#808080">01</font>&nbsp;<font color="#646464">@Entity</font><br />
<font color="#808080">02</font>&nbsp;<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">Client&nbsp;&nbsp;</font><font color="#000000">{</font><br />
<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Id&nbsp;@GeneratedValue</font><font color="#000000">(</font><font color="#000000">strategy=GenerationType.AUTO</font><font color="#000000">)</font><br />
<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">Long&nbsp;id;</font><br />
<font color="#808080">06</font>&nbsp;<font color="#ffffff"></font><br />
<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Column</font><font color="#000000">(</font><font color="#000000">unique=true,nullable=</font><font color="#7f0055"><b>false</b></font><font color="#000000">)</font><br />
<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;personalNumber;</font><br />
<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Column</font><br />
<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;name;</font><br />
<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">14</font>&nbsp;<font color="#000000">}</font></code></p>
</td>
<p>  <!-- end source code --><br />
   </tr>
</table>
</div>
<p>We see that a client has id which is used internally as an identifier. Moreover a client has a personal number which we are using as a business key. Then he has some other attributes as name. Notice that the personal number is obligatory and it has to be unique.</p>
<p>We can test flushing by the following code, using <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/jpa-test/tags/jpa-test-2.0/src/main/java/net/krecan/javacrumbs/jpatest/dao/jpa/JpaClientDao.java">ClinetDao</a>:</p>
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
<tr>
  <!-- start source code --></p>
<td nowrap="nowrap" valign="top" align="left">
    <code><br />
<font color="#808080">01</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Client&nbsp;client&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Client</font><font color="#000000">(</font><font color="#000000">PERSONAL_NUM</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Creating&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.createClient</font><font color="#000000">(</font><font color="#000000">client</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Changing&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">client.setName</font><font color="#000000">(</font><font color="#2a00ff">&#34;Carl&nbsp;von&nbsp;Bahnhof&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Deleting&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.deleteClient</font><font color="#000000">(</font><font color="#000000">client.getId</font><font color="#000000">())</font><font color="#000000">;</font><br />
<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Trying&nbsp;to&nbsp;load&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">assertNull</font><font color="#000000">(</font><font color="#000000">clientDao.loadClientWithPersonalNumberOrReturnNull</font><font color="#000000">(</font><font color="#000000">PERSONAL_NUM</font><font color="#000000">))</font><font color="#000000">;</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Creating&nbsp;second&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.createClient</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Client</font><font color="#000000">(</font><font color="#000000">PERSONAL_NUM</font><font color="#000000">))</font><font color="#000000">;</font></code></p>
</td>
<p>  <!-- end source code --><br />
   </tr>
</table>
</div>
<p>When it is executed on HSQLDB we get following output (we see my logging messages mixed with Hibernate SQL output).</p>
<div class="code">
<code><br />
Creating first client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
call identity()<br />
Changing first client<br />
Deleting first client<br />
Trying to load first client<br />
delete from Client where id=?<br />
select client0_.id as id2_, client0_.name as name2_, client0_.personalNumber as personal3_2_ from Client client0_ where client0_.personalNumber=?<br />
Creating second client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
call identity()<br />
</code>
</div>
<p>We see that inserts are called at once. They are not postponed until flush. In this case, Hibernate has to call insert at once because it has to get the client id from the database. (remember all non-transient entities have to have id) So inserts can not wait until flush, they have to be executed directly. In order to make our example more clear, we can change id generation strategy to sequence. </p>
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
<tr>
  <!-- start source code --></p>
<td nowrap="nowrap" valign="top" align="left">
    <code><br />
<font color="#808080">01</font>&nbsp;<font color="#646464">@Entity</font><br />
<font color="#808080">02</font>&nbsp;<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">Client&nbsp;&nbsp;</font><font color="#000000">{</font><br />
<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Id&nbsp;@GeneratedValue</font><font color="#000000">(</font><font color="#000000">strategy=GenerationType.SEQUENCE</font><font color="#000000">)</font><br />
<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">Long&nbsp;id;</font><br />
<font color="#808080">06</font>&nbsp;<font color="#ffffff"></font><br />
<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Column</font><font color="#000000">(</font><font color="#000000">unique=true,nullable=</font><font color="#7f0055"><b>false</b></font><font color="#000000">)</font><br />
<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;personalNumber;</font><br />
<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Column</font><br />
<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">String&nbsp;name;</font><br />
<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">.</font><br />
<font color="#808080">16</font>&nbsp;<font color="#000000">}</font></code></p>
</td>
<p>  <!-- end source code --><br />
   </tr>
</table>
</div>
<p>To get the client id, insert is not needed any more. It can be postponed until flush and we get following output</p>
<div class="code">
<code>Creating first client<br />
select next value for hibernate_sequence from dual_hibernate_sequence<br />
Changing first client<br />
Deleting first client<br />
Trying to load first client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
delete from Client where id=?<br />
select client0_.id as id2_, client0_.name as name2_, client0_.personalNumber as personal3_2_ from Client client0_ where client0_.personalNumber=?<br />
Creating second client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)</code>
</div>
<p>As you can see creation of the first client and his deletion is realized just before the select statement.  Changes have to be propagated to the DB so the select statement has access to changed data. You can notice, that there is no update, change of the name was already included into the insert statement. So far so good. Where is the problem? Lets comment out the query (You do not have to comment it out, in the real world it can be bypassed by the second-level cache).</p>
<div align="left" class="java">
<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
<tr>
  <!-- start source code --></p>
<td nowrap="nowrap" valign="top" align="left">
    <code><br />
<font color="#808080">01</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Client&nbsp;client&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Client</font><font color="#000000">(</font><font color="#000000">PERSONAL_NUM</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Creating&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.createClient</font><font color="#000000">(</font><font color="#000000">client</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Changing&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">client.setName</font><font color="#000000">(</font><font color="#2a00ff">&#34;Carl&nbsp;von&nbsp;Bahnhof&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Deleting&nbsp;first&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.deleteClient</font><font color="#000000">(</font><font color="#000000">client.getId</font><font color="#000000">())</font><font color="#000000">;</font><br />
<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//LOG.debug(&#34;Trying&nbsp;to&nbsp;load&nbsp;first&nbsp;client&#34;);</font><br />
<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//assertNull(clientDao.loadClientWithPersonalNumberOrReturnNull(PERSONAL_NUM));</font><br />
<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">LOG.debug</font><font color="#000000">(</font><font color="#2a00ff">&#34;Creating&nbsp;second&nbsp;client&#34;</font><font color="#000000">)</font><font color="#000000">;</font><br />
<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">clientDao.createClient</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">Client</font><font color="#000000">(</font><font color="#000000">PERSONAL_NUM</font><font color="#000000">))</font><font color="#000000">;</font></code></p>
</td>
<p>  <!-- end source code --><br />
   </tr>
</table>
</div>
<p>We get following output</p>
<div class="code">
<code>Creating first client<br />
select next value for hibernate_sequence from dual_hibernate_sequence<br />
Changing first client<br />
Deleting first client<br />
Creating second client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
SQL Error: 0, SQLState: null<br />
failed batch<br />
Could not synchronize database state with session<br />
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update<br />
	at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)<br />
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)<br />
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)<br />
	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)<br />
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)<br />
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)<br />
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)<br />
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)<br />
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)<br />
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)<br />
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)<br />
	at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)<br />
	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:438)<br />
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)<br />
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)<br />
	at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:346)<br />
	at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:199)<br />
	at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:340)<br />
	at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:351)<br />
	at org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:262)<br />
	at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)<br />
	at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)<br />
	at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)<br />
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)<br />
	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)<br />
	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)<br />
	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)<br />
	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)<br />
	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)<br />
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)<br />
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)<br />
Caused by: java.sql.BatchUpdateException: failed batch<br />
	at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)<br />
	at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)<br />
	at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)<br />
	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)<br />
	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)<br />
	... 31 more</code>
</div>
<p>Wow.  It looks like Hibernate is trying to insert both clients with the same personal number without deleting the first one. Lets try to remove uniqueness condition from the client and take a look at the output:</p>
<div class="code">
<code>Creating first client<br />
select next value for hibernate_sequence from dual_hibernate_sequence<br />
Changing first client<br />
Deleting first client<br />
Creating second client<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
insert into Client (name, personalNumber, id) values (?, ?, ?)<br />
delete from Client where id=?</code>
</div>
<p>Yes, Hibernate changed order of the commands! Without the unique constraint it does not matter, final result is the same. But with the constraint enabled, we can not use our code any more. Is it a bug? No, it is a feature. If you dig deep into the Hibernate source code, you will find following <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/event/def/AbstractFlushingEventListener.html#performExecutions(org.hibernate.event.EventSource)">comment </a></p>
<blockquote><p>Execute all SQL and second-level cache updates, in a<br />
	 special order so that foreign-key constraints cannot<br />
	 be violated:</p>
<ol>
<li> Inserts, in the order they were performed
<li> Updates
<li> Deletion of collection elements
<li> Insertion of collection elements
<li> Deletes, in the order they were performed
	 </ol>
</blockquote>
<p>And that is exactly our case. When flushing, Hibernate executes all inserts before delete statements. </p>
<p>So if we need to run our example, we have to force Hibernate to flush the delete before the second insert. The best way is to call entityManager.flush() explicitly just after the delete.  </p>
<p>To reiterate, Hibernate is using write-behind. All data manipulating statements are executed as late as possible. One exception are insert statements. Sometimes Hibernate needs to call insert in order to get the ID of the entity. The important point is, that <strong>order of the commands can be changed by Hibernate</strong>. Usually it does not matter, since transactions are atomic. But sometimes we can encounter interesting issues. Especially when using database constraints.</p>
<p><em>The source code can be downloaded from <a href="https://java-crumbs.svn.sourceforge.net/svnroot/java-crumbs/jpa-test/tags/jpa-test-2.0">SVN repository</a>.</em></p>
<p><em>Note: If you wonder why the hell I have started to write in something that looks almost like English when apparently I do even more mistakes than in Czech, the answer is simple. I just need to practice my English (apart from that I want to be world famous, not just known in Czech Republic)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.krecan.net/2008/01/05/flushing-hibernate/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
