【发布时间】:2020-10-06 20:43:51
【问题描述】:
我已经在 StackOverflow 上搜索并查看了所有现有答案,以了解我看到的错误。我尝试应用所有建议,但仍然无法摆脱这个可怕的错误
Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:143)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:475)
at com.myComp.core.persistence.HibernateUtils.find(HibernateUtils.java:82)
我正在使用 Spring boot 2.2.9 和 spring data jpa。我正在使用 SessionFactory 使用straight hibernate 实现来获取我的会话。我已经在我的 Service 上声明了 @Transactional 注释并从 Dao 类内部调用 sessionFactory.getCurrentSession() ,这就是我遇到此错误的地方。
这是我的 Spring xml 配置(我还没有使用 Java Config)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mv" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.myComp.core.persistence" />
<context:annotation-config />
<bean id="dataSourceassets" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5435/assets" />
<property name="username" value="postgres" />
<property name="password" value="postgres" />
<property name="initialSize" value="1" />
<property name="maxIdle" value="6" />
<property name="maxActive" value="6" />
<property name="minEvictableIdleTimeMillis" value="10000" />
<property name="maxWait" value="60000" />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="select 1" />
<property name="poolPreparedStatements" value="false" />
</bean>
<bean id="sessionFactoryassets" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" destroy-method="destroy">
<property name="dataSource">
<ref bean="dataSourceassets" />
</property>
<property name="mappingResources" value="/com/myComp/core/persistence/assets/ObjectMappings.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactoryassets" />
</property>
</bean>
<bean id="daoHelperassets" class="com.myComp.core.persistence.assets.AssetsDAOHelper">
<property name="sessionFactory">
<ref bean="sessionFactoryassets" />
</property>
</bean>
<bean id="masterAssetApi" class="com.myComp.core.persistence.assets.LocalAssetApiImpl">
<property name="daoHelper">
<ref bean="daoHelperassets" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>
我的类路径上有 CGLIB,Spring aspectj。我正在使用 java 1.8 运行它 我已经尝试使用 mode = proxy 和 aspectj 进行事务注释配置。我什至尝试过 proxy-target-class= true 和 false。我所有的尝试都失败了。 我在我的 Spring 容器之外提取 Spring 托管 bean“masterAssetApi”(服务类 LocalAssetApiImpl 的实例,其中贴有 @Transaction),并在我的主应用程序中调用我的服务方法。这不是像常规 Spring 应用程序那样的 Spring 应用程序。 这是一个示例代码
AssetApiImplInterface master = springContext.getBean("masterAssetApi");
master.getUser("20");
//getUser service method has read-only=true with @Transactional annotation
这里是 HibernateUtils 代码
public <T> java.util.List<T> find(final SessionFactory sessionFactory, final String queryString, final Map<String, Object> args, Class<T> cls, final String extendedErrorMessage)
throws PersistenceException
{
try
{
try
{
Session session = sessionFactory.getCurrentSession();
Query<T> qry = session.createQuery(queryString);
for(Map.Entry<String, Object> entry: args.entrySet()) {
qry.setParameter(entry.getKey(), entry.getValue());
}
List<T> ret = qry.list();
return ret;
}
catch (final HibernateException exception) {
throw SessionFactoryUtils.convertHibernateAccessException(exception);
}
}
catch (final BadSqlGrammarException bsg)
{
tracer.exception(bsg);
throw new PersistenceException(PersistenceException.SESSIONFAILURE, extendedErrorMessage, bsg);
}
catch (final DataAccessException dae)
{
tracer.exception(dae);
throw new PersistenceException(PersistenceException.SESSIONFAILURE, extendedErrorMessage, dae);
}
catch (final Exception ex)
{
tracer.exception(ex);
try
{
Thread.sleep(exceptionHiatus);
}
catch (final InterruptedException e)
{
tracer.debug("Slumber interrupted " + e.getMessage());
}
throw new PersistenceException(PersistenceException.SESSIONFAILURE, extendedErrorMessage, ex);
}
}
这里是调用堆栈跟踪。
ERROR 2020-10-06 20:20:41.123 [tomcat-p2p-23-Execute] com.myCorp.core.persistence.HibernateUtils: Exception:
org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:300)
at com.myCorp.core.persistence.HibernateUtils.find(HibernateUtils.java:91)
at com.myCorp.core.persistence.assets.Utils.find(Utils.java:157)
at com.myCorp.core.persistence.assets.SubGridImpl.getSubGridImpl(SubGridImpl.java:606)
at com.myCorp.core.persistence.assets.SubGridImpl.getSubGrid(SubGridImpl.java:498)
at com.myCorp.core.persistence.assets.AssetsDAOHelper.getSubGrid(AssetsDAOHelper.java:224)
at com.myCorp.core.persistence.assets.LocalAssetApiImpl.getSubGrid(LocalAssetApiImpl.java:405)
at com.myCorp.core.persistence.assets.LooseAssetApiManagerImpl.getSubGrid(LooseAssetApiManagerImpl.java:406)
@Transactional 注解围绕 LocalAssetApiImpl.getSubGrid(..)
注意:我使用 BeanFactory IOC 容器来加载我的 Spring Xml 而不是 ApplicationContext。您认为这可能是问题所在吗?
任何帮助将不胜感激。 谢谢
【问题讨论】:
-
请显示您的
HibernateUtils.find方法的代码。 -
感谢@GordonfromBlumberg 的快速回复。我编辑了我的原始问题以添加完整的查找代码。
标签: spring spring-boot hibernate spring-transactions