web-dev-qa-db-fra.com

Hibernate & Spring: Exception lors de la tentative de création d'une transaction

J'essaie donc d'utiliser Spring pour gérer pour la première fois des transactions en veille prolongée, et quelque chose ne va pas. Je ne sais pas quoi. J'ai consulté de nombreuses réponses similaires sur ce site et rien de ce que j'ai vu ne semble être correct.

Donc, je vais copier et coller une partie de mon code avec quelques explications et demander de l'aide ici.

Voici une trace de pile de l'exception que je reçois. Essentiellement, il semble qu’il essaie de trouver org.hibernate.engine.transaction.spi.transactioncontext, mais ne le peut pas.

Trace de pile d'exception

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)

Maintenant, j'ai cherché sur ce site, et la grande chose que j'ai vue était que cela signifiait que ma dépendance était mauvaise dans mon pom.xml. Le fait est que j'ai la version la plus récente de la dépendance hibernate-core dans mon pom. D'après ce que j'ai lu, c'est ce dont j'ai besoin pour ce cours.

dépendances 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>

En outre, j'ajoute la méthode réelle dans mon DAO que j'appelle. Cette méthode est ce que tente d'exécuter lorsque l'exception est levée.

Méthode 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;
}

Enfin, voici mon spring-context-data.xml. Il contient toute la configuration de mes beans de données pour le printemps, ainsi que des éléments de transaction:

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>

Donc, je n'ai aucune idée pourquoi cela se produit. J'ai double et triple vérifié ce que j'ai fait par rapport à ce que je vois en ligne, et je ne vois pas l'erreur. C'est la première fois que j'essaie d'utiliser la gestion des transactions Spring. Toute aide serait grandement appréciée.

PS. J'utilise Spring 4 & Hibernate 5 ensemble, si cela fait une différence.

15
user2223059

Dans votre POM, vous dépendez d'Hibernate 5, mais dans votre gestionnaire de transactions, vous utilisez Hibernate 4.

Modifiez votre gestionnaire de transactions pour qu’il corresponde à votre pom (c'est-à-dire de hibernate4 à hibernate5):

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

Si cela provoque une erreur de classe non trouvée, mettez à jour votre framework Spring à la version 4.2.2.

45
Tom Chamberlain

La classe qu'elle recherche fait référence à une classe qui n'existe que dans Hibernate 4.x http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/engine/transaction/ spi/package-summary.html

Mais pas plus dans 5.x http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/engine/transaction/spi/package-summary.html

Je pense donc que vous pourriez mélanger les dépendances Hibernate 4 et 5. Je ne pense pas que vous puissiez simplement changer de version en veille prolongée sans passer en revue toutes ses dépendances.

5
seba.wagner

Vous utilisez hibernate-5 mais vous demandez à spring d’utiliser hibernate-4 sessionFactory

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

et gestionnaire de transactions

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
2
beannayak

Pas sûr que ce soit le problème, mais comme vous pensez quelque chose de lié au pom.xml, essayez d'ajouter la dépendance du gestionnaire d'entités d'Hibernate. J'ai comparé votre pom.xml avec le mien et, en ce qui concerne les dépendances de l'hibernation, c'est celui qui manque.

0
Luan Rios Campos