<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=desmethans" rel="nofollow">Hans Desmet</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-6871?redirect=false" rel="nofollow">SPR-6871</a></strong> and commented</p>
<p dir="auto">When you submit a form, with databinding on a command object with indexed properties, the indexed properties of the command object are not filled in.<br>
I think this bug is related to the correction that happened in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398102921" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11506" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11506/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11506">#11506</a>.<br>
The characters [ and ] are not only removed from the id attrbute of the HTML elements, but also (unnessesary) from the name attribute of the HTML elements.</p>
<p dir="auto">You can see it happening via next example.<br>
When you type 10 and 20 in the input fields, the output to the console is: {Belgium=null, Switzerland=null}<br>
while the output should have been {Belgium=10, Switzerland=20}</p>
<p dir="auto">The class that acts as command object:</p>
<hr>
<p dir="auto">package org.example.entities;</p>
<p dir="auto">import java.util.LinkedHashMap;<br>
import java.util.Map;</p>
<p dir="auto">public class Continent {<br>
// key = name of country<br>
// Integer= number of inhabitants<br>
private Map&lt;String, Integer&gt; countries = new LinkedHashMap&lt;String, Integer&gt;();</p>
<p dir="auto">public Continent() {<br>
countries.put("Belgium", null);<br>
countries.put("Switzerland", null);<br>
}</p>
<p dir="auto">public void setCountries(Map&lt;String, Integer&gt; countries) {<br>
this.countries = countries;<br>
}</p>
<p dir="auto">public Map&lt;String, Integer&gt; getCountries() {<br>
return countries;<br>
}<br>
}</p>
<p dir="auto">The Controller class:</p>
<hr>
<p dir="auto">package org.example.web;</p>
<p dir="auto">import org.example.entities.Continent;<br>
import org.springframework.stereotype.Controller;<br>
import org.springframework.ui.Model;<br>
import org.springframework.validation.BindingResult;<br>
import org.springframework.web.bind.annotation.ModelAttribute;<br>
import org.springframework.web.bind.annotation.RequestMapping;<br>
import org.springframework.web.bind.annotation.RequestMethod;</p>
<p dir="auto"><code class="notranslate">@Controller</code><br>
public class ContinentController {<br>
<code class="notranslate">@RequestMapping</code>(value = "/continent.htm", method = RequestMethod.GET)<br>
public String continentForm(Model model) {<br>
Continent continent = new Continent();<br>
model.addAttribute(continent);<br>
return "continent.jsp";<br>
}</p>
<p dir="auto"><code class="notranslate">@RequestMapping</code>(value = "/continent.htm", method = RequestMethod.POST)<br>
public String continentForm(<code class="notranslate">@ModelAttribute</code> Continent continent,<br>
BindingResult bindingResult) {<br>
System.out.println(continent.getCountries()); // Here you can see the bug<br>
return "continent.jsp";<br>
}<br>
}</p>
<p dir="auto">continent.jsp</p>
<hr>
<p dir="auto">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</p>
<p dir="auto">&lt;%<code class="notranslate">@page</code> contentType="text/html" pageEncoding="UTF-8" session="false"%&gt;<br>
&lt;%<code class="notranslate">@taglib</code> prefix="c" uri="<a href="http://java.sun.com/jsp/jstl/core%22%%3E" rel="nofollow">http://java.sun.com/jsp/jstl/core"%&gt;</a><br>
&lt;%<code class="notranslate">@taglib</code> prefix="form" uri="<a href="http://www.springframework.org/tags/form%22%%3E" rel="nofollow">http://www.springframework.org/tags/form"%&gt;</a></p>
<p dir="auto">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br>
"<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd%22%3E" rel="nofollow">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</a><br>
&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml" rel="nofollow">http://www.w3.org/1999/xhtml</a>" xml:lang="nl" lang="nl"&gt;<br>
&lt;head&gt;<br>
&lt;title&gt;Continent example&lt;/title&gt;<br>
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;<br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
&lt;form:form commandName="continent"&gt;<br>
&lt;c:forEach items="${continent.countries}" var="entry"&gt;<br>
&lt;div&gt;<br>
&lt;form:label path="countries[${entry.key}]"&gt;${entry.key}&lt;/form:label&gt;<br>
&lt;form:input path="countries[${entry.key}]" /&gt;<br>
&lt;form:errors path="countries[${entry.key}]" /&gt;<br>
&lt;/div&gt;<br>
&lt;/c:forEach&gt;<br>
&lt;div&gt;&lt;input type="submit" /&gt;&lt;/div&gt;<br>
&lt;/form:form&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0.1</p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398103429" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11586" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11586/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11586">#11586</a> Indexed properties not set correctly in form tags (<em><strong>"is duplicated by"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398104153" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11702" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11702/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11702">#11702</a> form:select 3.0.1 regression bug when binding to a map (<em><strong>"is duplicated by"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398102921" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11506" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11506/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11506">#11506</a> form:checkbox tag creates invalid HTML id when bound to indexed property</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398092545" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/10055" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/10055/hovercard" href="https://github.com/spring-projects/spring-framework/issues/10055">#10055</a> org.springframework.web.servlet.tags.form.TagIdGenerator doesn't remove characters [] and double-quotes</li>
</ul>
<p dir="auto"><strong>Referenced from:</strong> commits <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/67b342d923c900323df169c32e27d9aa80fb8108/hovercard" href="https://github.com/spring-projects/spring-framework/commit/67b342d923c900323df169c32e27d9aa80fb8108"><tt>67b342d</tt></a></p>
<p dir="auto">3 votes, 8 watchers</p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=koen.serneels" rel="nofollow">Koen Serneels</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-9480?redirect=false" rel="nofollow">SPR-9480</a></strong> and commented</p>
<h4 dir="auto">Overview</h4>
<p dir="auto">There seems yet again another issue when using the Spring 3.1 - Hibernate4(.1.3) integration.</p>
<p dir="auto">This issue pops up so late since it only occurs in special circumstances: it has to do with the hibernate "smart" flushing which is not working.</p>
<p dir="auto">Hibernate guarantees that every modification you make (CUD) is flushed to the database prior any other operation that can possibly be related to the outstanding queries. This is to ensure that you don't work with stale data within the same transaction.</p>
<p dir="auto">For example:</p>
<ol dir="auto">
<li>Save an entity</li>
<li>Update the property of an entity</li>
<li>Query the entity using the value of the property changed in the previous step in the where clause</li>
</ol>
<p dir="auto">Hibernate will make sure that the changes by step2 (and possibly also the insert of step1 - if not done already) are flushed before step3 is executed (smart flush). If this didn't happen we would never be able to retrieve the entity in step3.</p>
<p dir="auto">The problem is that this smart flushing is not happening any more, since Hibernate does not detect that it is in a transaction.</p>
<p dir="auto">Taken from <code class="notranslate">SessionImpl</code> L1178:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
		errorIfClosed();
		if ( ! isTransactionInProgress() ) {
			// do not auto-flush while outside a transaction
			return false;
		}
		AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
		for ( AutoFlushEventListener listener : listeners( EventType.AUTO_FLUSH ) ) {
			listener.onAutoFlush( event );
		}
		return event.isFlushRequired();
	}"><pre class="notranslate"><code class="notranslate">protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
		errorIfClosed();
		if ( ! isTransactionInProgress() ) {
			// do not auto-flush while outside a transaction
			return false;
		}
		AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
		for ( AutoFlushEventListener listener : listeners( EventType.AUTO_FLUSH ) ) {
			listener.onAutoFlush( event );
		}
		return event.isFlushRequired();
	}
</code></pre></div>
<p dir="auto">What happens is before step3 is excecuted 'autoFlushIfRequired' is called (good). However isTransactionInProgress() will returns false. If you drill down in the code, you will see that it will call: <code class="notranslate">transactionCoordinator.isTransactionInProgress()</code> which will then call <code class="notranslate">getTransaction().isActive()</code>, which delegates to <code class="notranslate">JtaTransaction</code> L237:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="	@Override
	public boolean isActive() throws HibernateException {
		if ( getLocalStatus() != LocalStatus.ACTIVE ) {
			return false;
		}

		final int status;
		try {
			status = userTransaction.getStatus();
		}
		catch ( SystemException se ) {
			throw new TransactionException( &quot;Could not determine transaction status: &quot;, se );
		}
		return JtaStatusHelper.isActive( status );
	}"><pre class="notranslate"><code class="notranslate">	@Override
	public boolean isActive() throws HibernateException {
		if ( getLocalStatus() != LocalStatus.ACTIVE ) {
			return false;
		}

		final int status;
		try {
			status = userTransaction.getStatus();
		}
		catch ( SystemException se ) {
			throw new TransactionException( "Could not determine transaction status: ", se );
		}
		return JtaStatusHelper.isActive( status );
	}
</code></pre></div>
<p dir="auto">The LocalStatus will be "NOT_ACTIVE" and the userTransaction is null. Why? Because no one called "begin" on the JtaTransaction.</p>
<p dir="auto">In case of the HibernateTransactionManager it will call begin() once a transaction is started (in that case it will be JdbcTransaction rather then JtaTransaction).</p>
<p dir="auto">So while there is a transaction started and everything is working nicely there is still a part of Hibernate which is unaware that a transaction is indeed active, which results in strange behavior like illustrated here. Note that everything else is working OK, the  session will get flushed before transaction completion and everything will be in the database.</p>
<p dir="auto">However, within the transactions we now have a stale data problem. AFAIK this is a bug in the integration, since there are no more secret properties we can use to fix this one on hibernate level.</p>
<hr>
<h4 dir="auto">Examples</h4>
<p dir="auto">I supplied again 2 sample applications, one with hibernate3 and the same with hibernate4 to illustrate the issue.</p>
<p dir="auto">You can deploy the apps under context root hibernate3/hibernate4 and then point the browser to <code class="notranslate">http://&lt;host&gt;:&lt;port&gt;/hibernate3/Persist</code> or <code class="notranslate">http://&lt;host&gt;:&lt;port&gt;/hibernate4/Persist</code>.</p>
<p dir="auto">The Servlet looks up a bean from the application context. It will then call two transactional methods on the bean.</p>
<h6 dir="auto">Method 1</h6>
<ul dir="auto">
<li>Start transaction 1</li>
<li>Save an entity of type 'TestEntity'</li>
<li>Change the property 'value' to literal 'SomeValue' on the saved entity</li>
<li>Perform a query which selects all entities of type 'TestEntity' where their 'value' property matches 'SomeValue'</li>
<li>return result</li>
<li>display result</li>
<li>End transaction 1</li>
</ul>
<h6 dir="auto">Method 2</h6>
<ul dir="auto">
<li>Start transaction 2</li>
<li>Perform a query which selects all entities of type 'TestEntity' where their 'value' property matches 'SomeValue'</li>
<li>return result</li>
<li>display result</li>
<li>End transaction 2</li>
</ul>
<p dir="auto">With hibernate3 you will see this output:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Saving... Done. 
Result from read in TX: 1 Value:SomeValue 
Read from table in separate TX: 1 Value:SomeValue "><pre class="notranslate"><code class="notranslate">Saving... Done. 
Result from read in TX: 1 Value:SomeValue 
Read from table in separate TX: 1 Value:SomeValue 
</code></pre></div>
<p dir="auto">Which means that both in the same transaction and in the new transaction the data was found in database after saving/updating.</p>
<p dir="auto">In hibernate4 however:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Saving... Done. 
Result from read in TX: 
Read from table in separate TX: 1 Value:SomeValue "><pre class="notranslate"><code class="notranslate">Saving... Done. 
Result from read in TX: 
Read from table in separate TX: 1 Value:SomeValue 
</code></pre></div>
<p dir="auto">You see that in the same transaction the query did not return any results in the second output line. This is because the save of the entity and/or the update of the property where not flushed to database prior executing the query.</p>
<p dir="auto">Note: in the output we show two properties of the 'TestEntity'.</p>
<ul dir="auto">
<li>The value '1' in the output is the value of the 'id' property which is the PK of the entity and auto-increment.</li>
<li>'SomeValue' is the literal value we assigned to the 'value' property of the entity after we saved the entity.</li>
</ul>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.1.1</p>
<p dir="auto"><strong>Reference URL:</strong> <a href="http://forum.springsource.org/showthread.php?126363-Session-not-flushed-with-Hibernate-4-1-3-JTA-and-Spring-transaction-management-integ&amp;highlight=koen+serneels" rel="nofollow">http://forum.springsource.org/showthread.php?126363-Session-not-flushed-with-Hibernate-4-1-3-JTA-and-Spring-transaction-management-integ&amp;highlight=koen+serneels</a></p>
<p dir="auto"><strong>Attachments:</strong></p>
<ul dir="auto">
<li><a href="https://jira.spring.io/secure/attachment/19824/hibernate3.zip" rel="nofollow">hibernate3.zip</a> (<em>7.31 kB</em>)</li>
<li><a href="https://jira.spring.io/secure/attachment/19823/hibernate4.zip" rel="nofollow">hibernate4.zip</a> (<em>7.36 kB</em>)</li>
</ul>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398150499" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/14040" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/14040/hovercard" href="https://github.com/spring-projects/spring-framework/issues/14040">#14040</a> Session not flushed with Hibernate 4.1.3, JTA and Spring transaction management integration (<em><strong>"is duplicated by"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398188500" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/18421" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/18421/hovercard" href="https://github.com/spring-projects/spring-framework/issues/18421">#18421</a> Hibernate 4 Autoflush does not work with Spring OpenSessionInViewInterceptor</li>
</ul>
<p dir="auto"><strong>Referenced from:</strong> commits <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/efabc6bf18f791b050ed2e082040aa4ce3bb1aa6/hovercard" href="https://github.com/spring-projects/spring-framework/commit/efabc6bf18f791b050ed2e082040aa4ce3bb1aa6"><tt>efabc6b</tt></a>, <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/dda3197c77a0b66576ebccd629c5076c0403eaf5/hovercard" href="https://github.com/spring-projects/spring-framework/commit/dda3197c77a0b66576ebccd629c5076c0403eaf5"><tt>dda3197</tt></a></p>
<p dir="auto">5 votes, 8 watchers</p>