java无法获取当前线程HibernateString的transactionsynchronized会话
This same question has been asked so many times on SO, but please read my question fully before making it duplicates.
我不想使用基于注释的事务管理,所以我的问题与这里的问题不同
我的XML声明
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/comp::/env/jdbc/DS</value>
</property>
</bean>
<!-- Create SessionFactory , one instance per application only -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- Just for Testing Purpose -->
<property name="mappingResources">
<list>
<value>com/mycompany/hbmapping/platform/support/Currency.hbm.xml</value>
</list>
</property>
<!-- <property name="mappingDirectoryLocations"> <value>/WEB-INF/classes/com/mycompany/hbmapping</value>
</property> -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<!-- Cache related properties -->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory
</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/ehcache.xml</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTxManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
遵循DAO作为bean的声明
<bean id="currency" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>
com.mycompany.dao.platform.support.CurrencyDao
</value>
</property>
<property name="target">
<ref bean="currencyTarget" />
</property>
</bean>
<bean id="currencyTarget"
class="com.mycompany.dao.platform.support.CurrencyDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
我的建议
<tx:advice id="txAdvice" transaction-manager="hibernateTxManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"></tx:method>
<tx:method name="update*" propagation="REQUIRED"></tx:method>
<tx:method name="delete*" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
AOP配置
<aop:config>
<aop:pointcut
expression="within(com.mycompany.dao.platform.support.CurrencyDao)"
id="currencyPointCut" />
</aop:config>
<!-- applying advice on joint point -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut-ref="currencyPointCut" />
</aop:config>
我的刀
public class CurrencyDaoImpl extends BaseBusinessDao implements CurrencyDao {
/**
*
*/
public CurrencyDaoImpl() {
}
public Serializable save(CurrencyModel currency) {
Session session = getCurrentSession();
Serializable id = session.save(currency);
return id;
}
public void update(CurrencyModel currency) {
Session session = getCurrentSession();
session.update(currency);
}
public void delete(Serializable id) {
Session session = getCurrentSession();
session.delete(id);
}
}
我的模特
public class CurrencyModel extends BaseModel {
/**
*
*/
private static final long serialVersionUID = 6543232156842168468L;
private String currencyId;
/**
* name of the currency.
*/
private String currency;
private String trId;
/**
*
*/
public CurrencyModel() {
}
public String getCurrencyId() {
return currencyId;
}
public void setCurrencyId(String currencyId) {
this.currencyId = currencyId;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getTrId() {
return trId;
}
public void setTrId(String trId) {
this.trId = trId;
}
@Override
public int hashCode() {
return currency.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!this.getClass().equals(obj.getClass())) {
return false;
}
String anotherCurrency = ((CurrencyModel) obj).getCurrency();
if (getCurrency().equals(anotherCurrency)) {
return true;
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Currency for this instance is " + getCurrency());
return sb.toString();
}
}
我的Hibernate映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.mycompany.model.platform.support">
<class name="CurrencyModel" table="tblcurrency">
<id name="currencyId" column="currencyId">
<generator class="uuid"></generator>
</id>
<version name="version" column="version" type="long"></version>
<property name="rowStatus" column="rowStatus" not-null="true"></property>
<property name="currency" column="currency" not-null="true"></property>
<!-- this property needs to be replaces with transaction management root
object UserTransactionModel
-->
<property name="trId" not-null="true"></property>
</class>
</hibernate-mapping>
当我通过以下代码以编程方式运行此应用程序时
SimpleNamingContextBuilder scb = new SimpleNamingContextBuilder();
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://url:3306/db");
ds.setUsername("dtsnuser");
ds.setPassword("0okmnji9");
ds.setValidationQuery("select 1");
ds.setInitialSize(10);
ds.setMaxActive(20);
ds.setMaxIdle(10);
ds.setMaxWait(-1);
scb.bind("java:/comp::/env/jdbc/DS", ds);
scb.activate();
// setup bean factory
dlBeanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xbl = new XmlBeanDefinitionReader(dlBeanFactory);
xbl.loadBeanDefinitions(new FileSystemResource(
"src/main/webapp/WEB-INF/app-config/applicationContext.xml"));
currencyDao = (CurrencyDaoImpl) dlBeanFactory.getBean("currencyTarget");
currencyModel = new CurrencyModel();
currencyModel.setCurrency("INR");
id = UUID.randomUUID().toString();
currencyModel.setCurrencyId(id);
String trId = UUID.randomUUID().toString();
currencyModel.setTrId(trId);
它抛出以下异常
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:990) at com.mycompany.dao.base.BaseBusinessDao.getCurrentSession(BaseBusinessDao.java:41) at com.mycompany.dao.platform.support.CurrencyDaoImpl.delete(CurrencyDaoImpl.java:45) at com.mycompany.dao.platform.support.TestCurrencyDaoImpl.testDelete(TestCurrencyDaoImpl.java:130) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at junit.framework.TestCase.runTest(TestCase.java:154) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
我的数据源位于远程服务器上
我做错了什么? 建议是否应用不当?我能不能弄清楚这些建议是否得到了正确的应用
请不要建议我使用基于注释的方法,我暂时不能同意
谢谢 米希尔
# 1 楼答案
在网络应用中,这是处理aop事务的方式
希望这能提供一个想法