<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=sbrannen" rel="nofollow">Sam Brannen</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-9861?redirect=false" rel="nofollow">SPR-9861</a></strong> and commented</p>
<h4 dir="auto">Status Quo</h4>
<p dir="auto">When using SpEL's type function <code class="notranslate">T</code> to access a static constant, evaluation of the expression fails if the class referenced by the <code class="notranslate">T</code> function implements <code class="notranslate">java.util.Map</code>.</p>
<p dir="auto">For example, the following SpEL expression (taken from an excerpt from a project using Spring Integration) fails:</p>
<div class="highlight highlight-text-xml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;header name=&quot;#{T(org.springframework.integration.MessageHeaders).CORRELATION_ID}&quot; value=&quot;foo&quot; /&gt;"><pre class="notranslate">&lt;<span class="pl-ent">header</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>#{T(org.springframework.integration.MessageHeaders).CORRELATION_ID}<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>foo<span class="pl-pds">"</span></span> /&gt;</pre></div>
<p dir="auto">... with the following exception:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.util.Map 
        at org.springframework.context.expression.MapAccessor.canRead(MapAccessor.java:37) 
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:190)

        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)

        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) 
        at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93) 
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88) 
        at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:139)

        ... 47 more"><pre class="notranslate"><code class="notranslate">Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.util.Map 
        at org.springframework.context.expression.MapAccessor.canRead(MapAccessor.java:37) 
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:190)

        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)

        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) 
        at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93) 
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88) 
        at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:139)

        ... 47 more
</code></pre></div>
<hr>
<h4 dir="auto">Analysis</h4>
<p dir="auto">The reason for the above exception is that Spring Integration's <code class="notranslate">MessageHeaders</code> class implements <code class="notranslate">java.util.Map</code>. Thus the SpEL <code class="notranslate">MapAccessor</code> is added to the list of <em>candidate</em> property accessors to try in <code class="notranslate">PropertyOrFieldReference.getPropertyAccessorsToTry(Class&lt;?&gt;, ExpressionState)</code>, and <code class="notranslate">MapAccessor</code> ends up in the candidate list <strong>before</strong> <code class="notranslate">ReflectivePropertyAccessor</code>.</p>
<p dir="auto">So, when the expression is evaluated, it fails since the <code class="notranslate">T()</code> function returns a class instead of a <code class="notranslate">Map</code> instance. In other words, the <code class="notranslate">MapAccessor</code> assumes it is being passed an instance of <code class="notranslate">java.util.Map</code>, when it in fact receives an instance of <code class="notranslate">java.lang.Class</code> (i.e., the class reference returned by the <code class="notranslate">T()</code> function).</p>
<p dir="auto">In summary, <code class="notranslate">MapAccessor</code> obviously cannot be used to access static members. Thus the current implementation is completely broken in that the building of the candidate property accessor list does not take into account that the eventual property access may be <em>static</em>.</p>
<hr>
<h4 dir="auto">Deliverables</h4>
<ol dir="auto">
<li>Ensure that static members (i.e., constants) can be accessed in SpEL expressions using the <code class="notranslate">T()</code> function when the class passed to the <code class="notranslate">T()</code> function implements <code class="notranslate">java.util.Map</code>.</li>
</ol>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0 GA</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="398167005" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/16232" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/16232/hovercard" href="https://github.com/spring-projects/spring-framework/issues/16232">#16232</a> Referencing static field of class that extends Map in expression language causes class cast exception (<em><strong>"duplicates"</strong></em>)</li>
</ul>
<p dir="auto"><strong>Backported to:</strong> <a href="https://github.com/spring-projects/spring-framework/milestone/97?closed=1">3.2.9</a></p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=paul4christ79" rel="nofollow">Paul Benedict</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-4625?redirect=false" rel="nofollow">SPR-4625</a></strong> and commented</p>
<p dir="auto">It is sometimes desirable to perform a single operation in a separate session. For instance, if a DataIntegrityViolationException is returned in the current transaction, go back to the database to determine which column was duplicated. But for this to succeed, a separate session is required because Hibernate does not allow flushing, which is predicated by the aforementioned query.</p>
<p dir="auto"><a href="http://forum.springframework.org/archive/index.php/t-27112.html" rel="nofollow">http://forum.springframework.org/archive/index.php/t-27112.html</a></p>
<p dir="auto">Thus, I propose an extra method to complement execute or executeFind that would (use SessionFactoryUtils) to perform work in a separate session.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 2.5.2</p>