<style>
/* Changing the layout to use less space for mobiles */
@media screen and (max-device-width: 480px), screen and (-webkit-min-device-pixel-ratio: 2) {
#email-body { min-width: 30em !important; }
#email-page { padding: 8px !important; }
#email-banner { padding: 8px 8px 0 8px !important; }
#email-avatar { margin: 1px 8px 8px 0 !important; padding: 0 !important; }
#email-fields { padding: 0 8px 8px 8px !important; }
#email-gutter { width: 0 !important; }
}
</style>
<div id="email-body">
<table id="email-wrap" align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#f0f0f0;color:#000000;width:100%;">
<tr valign="top">
<td id="email-page" style="padding:16px !important;">
<table align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#ffffff;border:1px solid #bbbbbb;color:#000000;width:100%;">
<tr valign="top">
<td bgcolor="#3e4c4e" style="background-color:#3e4c4e;color:#ffffff;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;line-height:1;"><img src="https://www.jboss.org/dms/hibernate/images/jira/jiraheader_hibernate.png" alt="" style="vertical-align:top;" /></td>
</tr><tr valign="top">
<td id="email-banner" style="padding:32px 32px 0 32px;">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;">
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;padding:0;">
<img id="email-avatar" src="https://hibernate.onjira.com/secure/useravatar?ownerId=hardy.ferentschik&avatarId=10342" alt="" height="48" width="48" border="0" align="left" style="padding:0;margin: 0 16px 16px 0;" />
<div id="email-action" style="padding: 0 0 8px 0;font-size:12px;line-height:18px;">
<a class="user-hover" rel="hardy.ferentschik" id="email_hardy.ferentschik" href="https://hibernate.onjira.com/secure/ViewProfile.jspa?name=hardy.ferentschik" style="color:#6c797f;">Hardy Ferentschik</a>
updated <img src="https://hibernate.onjira.com/images/icons/bug.gif" height="16" width="16" border="0" align="absmiddle" alt="Bug"> <a style='color:#6c797f;text-decoration:none;' href='https://hibernate.onjira.com/browse/HHH-7376'>HHH-7376</a>
</div>
<div id="email-summary" style="font-size:16px;line-height:20px;padding:2px 0 16px 0;">
<a style='color:#6c797f;text-decoration:none;' href='https://hibernate.onjira.com/browse/HHH-7376'><strong>JtaTransactionFactory should always set UserTransaction</strong></a>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr valign="top">
<td id="email-fields" style="padding:0 32px 32px 32px;">
<table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%">
<tr valign="top">
<td id="email-gutter" style="width:64px;white-space:nowrap;"></td>
<td>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Change By:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<a class="user-hover" rel="hardy.ferentschik" id="email_hardy.ferentschik" href="https://hibernate.onjira.com/secure/ViewProfile.jspa?name=hardy.ferentschik" style="color:#6c797f;">Hardy Ferentschik</a>
(07/Jun/12 5:38 AM)
</td>
</tr>
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Description:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<span class="diffremovedchars" style="background-color:#ffe7e7;text-decoration:line-through;"><br></span>
<span class="diffcontext">In Hibernate 3.6.10, when creating JtaTransaction from JtaTransactionFactory UserTransaction was always setted:<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}<br></span>
<span class="diffcontext">public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) throws HibernateException {<br> UserTransaction ut = getUserTransaction();<br> return new JTATransaction( ut, jdbcContext, transactionContext );<br>}<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}</span>
<span class="diffcontext"><br></span>
<span class="diffaddedchars" style="background-color:#ddfade;"><br></span>
<span class="diffcontext">This behavior changed in Hibernate 4.0.1 as UserTransaction will only get setted if explicitly beginning a new transaction ; UserTransaction is no longer passed by the JtaTransactionFactory:<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}<br></span>
<span class="diffcontext">protected void doBegin() {<br> LOG.debug( "begin" );<br> <br> userTransaction = jtaPlatform().retrieveUserTransaction();<br> if ( userTransaction == null ) {<br> throw new TransactionException( "Unable to locate JTA UserTransaction" );<br> }<br> ...<br>}<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}</span>
<span class="diffcontext"><br>This change of affect the JtaTransactionFactory::isJoinableJtaTransaction method behavior:<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}<br></span>
<span class="diffcontext">public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JtaTransaction transaction) {<br> try {<br> // Essentially:<br> // 1) If we have a local (Hibernate) transaction in progress<br> // and it already has the UserTransaction cached, use that<br> // UserTransaction to determine the status.<br> // 2) If a transaction manager has been located, use<br> // that transaction manager to determine the status.<br> // 3) Finally, as the last resort, try to lookup the<br> // UserTransaction via JNDI and use that to determine the<br> // status.<br> if ( transaction != null ) {<br> UserTransaction ut = transaction.getUserTransaction();<br> if ( ut != null ) {<br> return JtaStatusHelper.isActive( ut );<br> }<br> }<br> ...<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}</span>
<span class="diffcontext">        <br>Hibernate 4.0.1: transaction.getUserTransaction() == null<br>Hibernate 3.6.10: transaction.getUserTransaction() != null<br><br>as stated in javadoc, if user transaction as not been set in 1), it will fallback on jtaPlatform.retrieveTransactionManager 2) and will later fail with "proxy handle is no longer valid" as UserTransaction as not been set.<br>see forum reference : https://forum.hibernate.org/viewtopic.php?f=1&t=1014848<br><br>As a workaround I've hacked the JtaTransaction::getUserTransaction() to:<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}<br></span>
<span class="diffcontext"> private static Field localStatus;<br> @SuppressWarnings( {"UnusedDeclaration"})<br> public UserTransaction getUserTransaction() {<br> if (userTransaction != null){<br> return userTransaction;<br> }<br> userTransaction = jtaPlatform().retrieveUserTransaction();<br> if ( userTransaction == null ) {<br> throw new TransactionException( "Unable to locate JTA UserTransaction" );<br> }<br> if (localStatus == null){<br> try{<br> localStatus = AbstractTransactionImpl.class.getDeclaredField("localStatus");<br> localStatus.setAccessible(true);<br> }<br> catch (Exception e){<br> throw new RuntimeException(e);<br> }<br> }<br> try{<br> localStatus.set(this, LocalStatus.ACTIVE);<br> }<br> catch (Exception e){<br> throw new RuntimeException(e);<br> }<br> <br> return userTransaction;<br> }<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}</span>
<span class="diffcontext"><br>which seem to resolve the issue.<br><br>Here's how Configuration and SessionFactory are created :<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}<br></span>
<span class="diffcontext">configuration = new Configuration();<br>configuration.setProperty("hibernate.connection.datasource", datasourceName);<br>// Hibernate Configuration Properties<br>configuration.setProperty("hibernate.dialect", "com.XXX.MySQL5InnoDBDialect");<br>configuration.setProperty("hibernate.show_sql", "false");<br>configuration.setProperty("hibernate.format_sql", "false");<br>configuration.setProperty("hibernate.max_fetch_depth", "0"); // recommended values between 0 and 3<br>configuration.setProperty("hibernate.default_batch_fetch_size", "16"); // recommended values 4, 8, 16<br>configuration.setProperty("hibernate.order_updates", "true");<br>configuration.setProperty("hibernate.generate_statistics", "true");<br>configuration.setProperty("hibernate.use_sql_comments", "false");<br>// Hibernate JDBC and Connection Properties<br>configuration.setProperty("hibernate.jdbc.batch_size", "30"); // recommended values between 5 and 30<br>configuration.setProperty("hibernate.jdbc.batch_versioned_data", "true");<br>configuration.setProperty("hibernate.connection.provider_class", "com.XXX.DatasourceConnectionProvider");<br>// Hibernate Cache Properties<br>configuration.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.infinispan.InfinispanRegionFactory");<br>configuration.setProperty("hibernate.cache.use_minimal_puts", "true");<br>configuration.setProperty("hibernate.cache.use_query_cache", "false"); // true to activate L2 cache<br>configuration.setProperty("hibernate.cache.use_second_level_cache", "false"); // true to activate L2 cache<br>configuration.setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JTATransactionFactory");<br>configuration.setProperty("hibernate.transaction.manager_lookup_class", "org.hibernate.transaction.JBossTransactionManagerLookup");<br>configuration.setProperty("jta.UserTransaction", JBossAppServerJtaPlatform.UT_NAME);<br>configuration.setProperty("hibernate.transaction.jta.platform", "org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform");<br>// Miscellaneous Properties<br>configuration.setProperty("hibernate.current_session_context_class", "jta");<br>// deactivate hibernate envers<br>configuration.setProperty("hibernate.listeners.envers.autoRegister", "false");<br><br>BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().withApplicationClassLoader(this.getClass().getClassLoader()).build();<br>ServiceRegistry serviceRegistry = new ServiceRegistryBuilder(bootstrapServiceRegistry).applySettings(configuration.getProperties()).buildServiceRegistry();<br>SessionFactory sessionFactory = (SessionFactory) configuration.buildSessionFactory(serviceRegistry);<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;">{code}</span>
<span class="diffcontext"><br></span>
<span class="diffaddedchars" style="background-color:#ddfade;"><br></span>
<span class="diffcontext">Is there any reason why UserTransaction is not injected anymore at creation time ? Is my [ugly] workaround valid ?<br><br>Thanks,<br></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td><!-- End #email-page -->
</tr>
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:10px;line-height:14px;padding: 0 16px 16px 16px;text-align:center;">
This message is automatically generated by JIRA.<br />
If you think it was sent incorrectly, please contact your <a style='color:#6c797f;' href='https://hibernate.onjira.com/secure/ContactAdministrators!default.jspa'>JIRA administrators</a>.<br />
For more information on JIRA, see: <a style='color:#6c797f;' href='http://www.atlassian.com/software/jira'>http://www.atlassian.com/software/jira</a>
</td>
</tr>
</table><!-- End #email-wrap -->
</div><!-- End #email-body -->