java Hibernate & Spring:尝试创建事务时出现异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32898333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate & Spring: Exception when trying to create a transaction
提问by user2223059
So I'm trying to use Spring to manage hibernate transactions for the first time, and something's going wrong. I'm not sure what. I've looked at a bunch of similar answers on this site and nothing I've seen seems to be right.
所以我第一次尝试使用Spring来管理hibernate事务,出了点问题。我不确定是什么。我在这个网站上看过一堆类似的答案,但我所看到的似乎都不对。
So, I'm gonna copy and paste a bunch of my code with some explanations and ask for help here.
所以,我将复制并粘贴一堆我的代码并附上一些解释,并在此处寻求帮助。
Here is a stack trace of the exception I'm getting. Essentially, It seems that it's trying to find org.hibernate.engine.transaction.spi.transactioncontext, and can't.
这是我得到的异常的堆栈跟踪。本质上,它似乎试图找到 org.hibernate.engine.transaction.spi.transactioncontext,但不能。
Exception stack trace
异常堆栈跟踪
EXCEPTION: Could not open Hibernate Session for transaction; nested exception is java.lang.NoClassDefFoundError: org/hibernate/engine/transaction/spi/TransactionContext
org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy42.getSavedPortfolios(Unknown Source)
io.craigmiller160.stockmarket.controller.StockMarketController.showOpenPortfolioDialog(StockMarketController.java:994)
io.craigmiller160.stockmarket.controller.StockMarketController.parseEvent(StockMarketController.java:431)
io.craigmiller160.stockmarket.controller.StockMarketController.processEvent(StockMarketController.java:336)
io.craigmiller160.mvp.concurrent.AbstractConcurrentListenerController.run(AbstractConcurrentListenerController.java:209)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Now, I've searched this site, and the big thing I saw was that this means I have a dependency wrong in my pom.xml. The thing is, I have the most up-to-date version of the hibernate-core dependency in my pom. From what I've read, that's what I need for this class.
现在,我搜索了这个站点,我看到的最重要的事情是这意味着我的 pom.xml 中有一个依赖项错误。问题是,我的 pom 中有最新版本的 hibernate-core 依赖项。从我所读到的,这就是我在这门课上所需要的。
pom.xml dependencies
pom.xml 依赖
<dependencies>
<!-- JUnit Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MVP Framework -->
<dependency>
<groupId>io.craigmiller160.mvp</groupId>
<artifactId>mvp-framework</artifactId>
<version>2.1.1</version>
</dependency>
<!-- MigLayout -->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>5.0</version>
</dependency>
<!-- JFreeChart -->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
<!-- Java Concurrency In Practice Annotations -->
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
</dependency>
<!-- Joda Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.8.2</version>
</dependency>
<!-- MySQL ConnectorJ -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<!-- Spring Framework Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Framework Beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Framework Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Hibernate Core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.1.Final</version>
</dependency>
<!-- XML Framework -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- Code Generation library -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!-- Apache Commons Logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- LOG4J API -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- LOG4J Core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- SLF4J/LOG4J Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- LOG4J/Commons Logging Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- AspectJ Runtime -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- AspectJ Weaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Apache Database Connection Pooling -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
Also, I'm adding the actual method in my DAO that I'm calling. This method is what is attempting to run when the exception is thrown.
另外,我在我调用的 DAO 中添加了实际的方法。此方法是在抛出异常时尝试运行的方法。
DAO method:
DAO方法:
@Transactional
@Override
@SuppressWarnings("unchecked") //hibernate list() method doesn't support generics
public List<String> getSavedPortfolios() throws HibernateException {
List<String> portfolioNames = new ArrayList<>();
List<SQLPortfolioModel> portfolioList = sessionFactory.getCurrentSession()
.createCriteria(PortfolioModel.class)
.list();
for(SQLPortfolioModel portfolio : portfolioList){
int id = portfolio.getUserID();
String name = portfolio.getPortfolioName();
BigDecimal netWorth = portfolio.getNetWorth();
Calendar timestamp = portfolio.getTimestamp();
String fileName = String.format("%1$d-%2$s-%3$s-"
+"%4$s", id, name, moneyFormat.format(netWorth),
timestampFormat.format(timestamp.getTime()));
portfolioNames.add(fileName);
}
return portfolioNames;
}
Lastly, here is my spring-context-data.xml. It contains all the configuration for my data beans for spring, plus the transaction stuff:
最后,这是我的 spring-context-data.xml。它包含我的 spring 数据 bean 的所有配置,以及事务内容:
spring-context-data.xml
spring-context-data.xml
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Sets annotation-driven transactions -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- DataSource object for providing database connections -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/stockmarket"/>
<property name="username" value="stockmarket"/>
<property name="password" value="stockmarket"/>
</bean>
<!-- SessionFactory object for creating sessions for database access -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- <property name="configLocation" value="classpath:hibernate.cfg.xml"/>-->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="connection.pool_size">1</prop>
<prop key="show_sql">false</prop>
<!-- Might need this one below for transactions, not sure yet -->
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>io.craigmiller160.stockmarket.stock.AbstractStock</value>
<value>io.craigmiller160.stockmarket.stock.OwnedStock</value>
<value>io.craigmiller160.stockmarket.stock.DefaultStock</value>
<value>io.craigmiller160.stockmarket.stock.DefaultOwnedStock</value>
<value>io.craigmiller160.stockmarket.model.PortfolioModel</value>
<value>io.craigmiller160.stockmarket.model.SQLPortfolioModel</value>
</list>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- HibernateDAO class for performing database operations -->
<bean id="hibernateDao" class="io.craigmiller160.stockmarket.controller.HibernatePortfolioDAO"
destroy-method="closeFactory">
<constructor-arg ref="sessionFactory"/>
</bean>
</beans>
So I just have no idea why this is happening. I've double and triple checked what I did versus what I'm seeing online, and I can't see the mistake. This is my first time trying to use Spring transaction management. Any help would be greatly appreciated.
所以我只是不知道为什么会这样。我已经对我所做的与我在网上看到的进行了两次和三次检查,但我看不到错误。这是我第一次尝试使用 Spring 事务管理。任何帮助将不胜感激。
PS. I'm using Spring 4 & Hibernate 5 together, if that makes a difference.
附注。我正在使用 Spring 4 和 Hibernate 5,如果这有区别的话。
回答by Tom Chamberlain
In your POM you are depending on Hibernate 5, but in your transaction manager, you are using Hibernate 4.
在您的 POM 中,您依赖于 Hibernate 5,但在您的事务管理器中,您使用的是 Hibernate 4。
Change your transacation manager to match your pom (i.e. from hibernate4 to hibernate5):
更改您的事务管理器以匹配您的 pom(即从 hibernate4 到 hibernate5):
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
If that causes a class not found error, upgrade your spring framework to 4.2.2
如果这导致找不到类错误,请将您的 spring 框架升级到 4.2.2
回答by seba.wagner
The class it is looking for is referring to a class that only exists in Hibernate 4.x http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/engine/transaction/spi/package-summary.html
它正在寻找的类指的是只存在于 Hibernate 4.x http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/engine/transaction/spi/package-summary 中的类.html
But no more in 5.x http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/engine/transaction/spi/package-summary.html
但在 5.x 中不再有 http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/engine/transaction/spi/package-summary.html
So I think you might be mixing Hibernate 4 and 5 dependencies. I don't think you can just switch the hibernate version without reviewing all of its dependencies.
所以我认为您可能正在混合 Hibernate 4 和 5 依赖项。我认为您不能在不查看所有依赖项的情况下切换休眠版本。
回答by Binayak
You are using hibernate-5 but you are asking spring to use hibernate-4 sessionFactory
您正在使用 hibernate-5 但您要求 spring 使用 hibernate-4 sessionFactory
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
and transaction manager
和交易经理
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
回答by Luan Rios Campos
Not sure if this is the problem, but since you think is something related to the pom.xml try adding the hibernate's entity manager dependency. I compared your pom.xml with mine and, with regards to the hibernate's dependencies, this is the one lacking.
不确定这是否是问题所在,但由于您认为与 pom.xml 相关,请尝试添加 hibernate 的实体管理器依赖项。我将您的 pom.xml 与我的进行了比较,关于休眠的依赖项,这是缺少的。
回答by krishan kansal
I was getting the same problem and my problem get solved by updating
我遇到了同样的问题,我的问题通过更新得到解决
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>