我試圖縮短這個與我認爲相關的東西,我希望這是足夠的,而不是壓倒性的。請幫忙!爲什麼我的(spring)HibernateTransactionManager不能在wicket中工作?
我將一個小檢票+的DataBinder + hibernate的 Web應用程序使用檢票+ Spring + Hibernate的。我有一個DAO服務類,由Spring注入一個hibernate SessionFactory。我能夠使用會話工廠執行只讀操作(默認情況下,自動提交功能處於打開狀態)。我想要做的是使用HibernateTransactionManager和@Transactional註釋來執行事務操作。
我定義了一個DAO服務實現,它使用一個注入的SessionFactory的方法標記@Transactional:
public class DAO implements IDAO {
@SpringBean
private SessionFactory sessionFactory;
public DAO() {
super();
}
@Transactional
public Object execute(SessionUnit sessionUnit) {
Session sess = sessionFactory.getCurrentSession();
Object result;
result = sessionUnit.run(sess);
sess.flush();
return result;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Transactional
public boolean isObjectPersistent(Object object) {
return sessionFactory.getCurrentSession().contains(object);
}
}
當我嘗試調用isObjectPersistent()
,我得到一個休眠例外,因爲沒有人叫session.beginTransaction ():
Caused by: org.hibernate.HibernateException: contains is not valid without active transaction
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:338)
at $Proxy38.contains(Unknown Source)
at com.gorkwobbler.shadowrun.karma.db.hibernate.DAO.isObjectPersistent(DAO.java:35)
(reflection stuff omitted...)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
(reflection stuff omitted...)
at org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler.invoke(LazyInitProxyFactory.java:416)
at org.apache.wicket.proxy.$Proxy36.isObjectPersistent(Unknown Source)
我也是從完整的堆棧跟蹤時會被調用的OpenSessionInViewFilter注意到,我不知道這是相關的。讓我知道你是否需要堆棧跟蹤的其餘部分。
如果我創建一個自定義WebRequestCycle子類,它開始一個事務,我可以通過這個。這在我看來破壞了@Transactional的目的,而且我的實現也變成了問題。
這裏是我的applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Reference: http://wicketinaction.com/2009/06/wicketspringhibernate-configuration/ -->
<beans default-autowire="autodetect"
xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- bean definitions -->
<bean id="wicketApplication" class="com.gorkwobbler.shadowrun.karma.view.wicket.core.WicketApplication" />
<bean id="placeholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<value>classpath*:/application.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>${jdbc.driver}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<!-- setup transaction manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation">
<value>classpath:/hibernate.cfg.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.gorkwobbler.shadowrun.karma.domain</value>
<value>com.gorkwobbler.shadowrun.karma.domain.*</value>
</list>
</property>
</bean>
<bean id="dao"
class="com.gorkwobbler.shadowrun.karma.db.hibernate.DAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- Don't know what this is for, but it was in the sample config I started from -->
<!-- <context:component-scan base-package="com.gorkwobbler.shadowrun.karma" /> -->
</beans>
我怎樣才能讓我的DAO開始交易,在該方法中,或者在錯誤回滾月底提交?我想使用可能的最小/標準配置;如果給出選擇,我更喜歡對XML的註釋。
編輯:
我修改上面的ApplicationContext來刪除AOP配置的東西,這是不工作的,反正。
使用調試器時,我確定存儲在TransactionInterceptor的會話持有者映射中的SessionImpl與SessionOmp方法中檢索到的SessionImpl不同,當我調用sessionFactory.getCurrentSession()時。任何人都可以解釋爲什麼這是?我究竟做錯了什麼?魔法不起作用。 =(
編輯
我也注意到在我的控制檯以下消息啓動時:
WARN - stractEhcacheRegionFactory - No TransactionManagerLookup found in Hibernate config, XA Caches will be participating in the two-phase commit!
我有同樣的問題,但我當前的會話上下文類設置爲: org.hibernate.context.ThreadLocalSessionContext 刪除它會引發異常 –
Eildosa
2012-06-15 09:13:56