我正在将JBoss 5应用程序上的旧版Spring 3,Hibernate 3,JTA迁移到最新版本(Spring 4.1.0.RELEASE,Hibernate 4.3.6.Final,JBoss Wildfly 8.1)。似乎Spring 4.1.0.RELEASE和Hibernate 4.3.6.Final做 NOT 一起支持使用 LocalSessionFactoryBean 和 HibernateTransactionManager <进行写操作的事务/ em>如下配置。只读获取操作似乎正常工作。
要迁移,org.springframework.orm。 hibernate3 .support.HibernateDaoSupport已更新为org.springframework.orm。 hibernate4 .support.HibernateDaoSupport。有问题的代码试图用 getHibernateTemplate()。saveOrUpdate(myObject); 保存,其中 myObject 是要保存的对象(在Spring3 + Hibernate 3中有效)。代码编译但在运行时我看到代码在以下处调用异常:
问题:
由 getSessionFactory()。getCurrentSession()触发的Hibernate会话的打开/关闭是否会调用问题(性能还是其他)?如果是这样,配置中是否有可以设置以避免它的东西?
在处理异常时,HibernateTemplate始终将新打开的会话设置为FlushMode.MANUAL。而且,在调试器中,我看到这无法检查写操作:
请注意,设置 getHibernateTemplate()。setCheckWriteOperations(false); 绕过Spring检查,但 getHibernateTemplate()。saveOrUpdate(myObject)调用在Hibernate代码中无声地失败没有抛出任何异常,也没有任何东西写入数据库。我需要做什么配置更改才能提交写操作?
Bean定义:
这里是来自application-context.xml Spring配置文件的相关bean定义片段:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven/>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="false">
<property name="jndiName" value="java:jboss/datasources/jdbc/my-srvr"/>
<property name="cache">
<value>false</value>
</property>
<property name="proxyInterface">
<value>javax.sql.DataSource</value>
</property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="true">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/mydomain/dao/Hib.hib.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<!-- JTA -->
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory</prop>
<prop key="hibernate.flushMode">AUTO</prop>
<prop key="jta.UserTransaction">java:jboss/UserTransaction</prop>
<prop key="jta.TransactionManager">java:jboss/TransactionManager</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform</prop>
<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.JTASessionContext</prop>
<!--prop key="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</prop-->
<!-- Turn caching off to focus on JTA issues-->
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<!--prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop-->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">sample-ehcache.xml</prop>
</props>
</property>
<!--No equivalent class in Spring4; comment out for now-->
<!--property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property-->
</bean>
注意:遗留bean定义的一个重要更改是从org.springframework。 transaction.jta.JtaTransactionManager 更改为org.springframework。 orm.hibernate4.HibernateTransactionManager
JNDI查看
一旦部署,JBoss Wildfly中的JNDI视图如下(当然对象引用会改变每个部署):
java:jboss
TransactionManager TransactionManagerDelegate @ 49e6e9c8
TransactionSynchronizationRegistry TransactionSynchronizationRegistryImple @ 40cd0746
UserTransaction UserTransaction
jaas java:jboss / jaas / Context proxy
答案 0 :(得分:0)
所以我终于让写操作在遗留代码中工作了。以下是我为使代码工作所遵循的步骤:
确保您使用的是Hibernate特定的事务管理器 org.springframework.orm.hibernate4.HibernateTransactionManager 和 NOT 通用 org.springframework。 transaction.jta.JtaTransactionManager
验证是否已启用注释。
将 @Transactional 注释(org.springframework.transaction.annotation.Transactional)添加到执行保存/更新/删除等操作的方法中。遗留代码在不需要此注释的情况下工作,但现在,对于最新版本,启用写入操作必需。
在我的情况下,我在添加注释后遇到了一堆自动布线问题。根本原因是,某些实现类(而不是接口)被用于在@Service级别类中自动连接属性。更改引用以使用修复该问题的接口。您可以在其他主题上阅读有关它的更多信息,例如this one。
我必须搜索并重复这些步骤来修复遗留代码中的所有此类实例。请注意,通过OpenSessionInViewFilter全局设置 FlushMode 为 AUTO 并不是一个干净的解决方案;有一个很好的理由,为什么Spring默认将 FlushMode 设置为 MANUAL 。当存在@Transactional注释时,Spring会进行必要的运行时调整以支持写操作。我一直调试到Hibernate org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl类,Jta同步与上面的设置一起正常工作。希望这有助于任何人试图将遗留代码迁移到最新版本。