16

所以我第一次尝试使用 Spring 来管理休眠事务,结果出了点问题。我不确定是什么。我在这个网站上查看了一堆类似的答案,但我所看到的似乎都是正确的。

所以,我将复制并粘贴一堆我的代码并附上一些解释,并在这里寻求帮助。

这是我得到的异常的堆栈跟踪。本质上,它似乎试图找到 org.hibernate.engine.transaction.spi.transactioncontext,但不能。

异常堆栈跟踪

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$1.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)

现在,我搜索了这个站点,我看到的最重要的事情是,这意味着我的 pom.xml 中存在依赖错误。问题是,我的 pom.xml 中有最新版本的 hibernate-core 依赖项。从我所读到的,这就是我这门课所需要的。

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>

另外,我正在调用的 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;
}

最后,这是我的 spring-context-data.xml。它包含我的 spring 数据 bean 的所有配置,以及事务内容:

弹簧上下文数据.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>

所以我只是不知道为什么会这样。我已经两次和三次检查了我所做的与我在网上看到的内容,我看不到错误。这是我第一次尝试使用 Spring 事务管理。任何帮助将不胜感激。

PS。我正在一起使用 Spring 4 和 Hibernate 5,如果这有所作为的话。

4

5 回答 5

45

在您的 POM 中,您依赖于 Hibernate 5,但在您的事务管理器中,您使用的是 Hibernate 4。

更改您的事务管理器以匹配您的 pom(即从 hibernate4 到 hibernate5):

<bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

如果这导致找不到类错误,请将您的 spring 框架升级到 4.2.2

于 2015-10-29T11:25:38.747 回答
5

它正在寻找的类是指仅存在于 Hibernate 4.x http://docs.jboss.org/hibernate/orm/4.3/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

所以我认为你可能混合了 Hibernate 4 和 5 依赖项。我不认为你可以在不查看所有依赖项的情况下切换休眠版本。

于 2015-10-01T23:47:09.213 回答
2

您正在使用 hibernate-5 但您要求 spring 使用 hibernate-4 sessionFactory

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

和事务管理器

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
于 2016-05-31T00:16:42.923 回答
0

不确定这是否是问题,但由于您认为与 pom.xml 有关,请尝试添加休眠的实体管理器依赖项。我将您的 pom.xml 与我的进行了比较,关于休眠的依赖项,这是缺少的。

于 2015-10-01T23:42:29.827 回答
-3

我遇到了同样的问题,我的问题通过更新得到了解决

<bean id="transactionManager"
    class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>

于 2016-01-29T23:38:22.843 回答