web-dev-qa-db-fra.com

Hibernate n'a pas pu obtenir la session synchronisée par transaction pour le thread actuel

J'ai eu un problème similaire à celui de nombreuses personnes, mais je n'arrive pas à comprendre ce qui ne va pas dans mon cas spécifique. Je fais un simple appel à la base de données pour tester la connexion à la base de données et Hibernate lève l'exception suivante:

Exception in thread "main" 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:1014)
at boardwalk.computeServer.dao.DbDaoHibernateImpl.getInterpolationJob(DbDaoHibernateImpl.Java:73)
at boardwalk.computeServer.ComputeServer.test(ComputeServer.Java:39)
at boardwalk.computeServer.ComputeServer.main(ComputeServer.Java:32)

Voici le code et la configuration pertinents:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema  instance" xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-    4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>boardwalk</groupId>
  <artifactId>computeServer</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <name>marketserver</name>
  <url>http://maven.Apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-Java</artifactId>
    <version>5.1.33</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>jta</artifactId>
    <version>1.1</version>
  </dependency>
  <dependency>
    <groupId>activesoap</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.3</version>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.3.7.Final</version>
  </dependency>
  <dependency>
    <groupId>org.Apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.10.0</version>
  </dependency>
  <dependency>
    <groupId>org.Apache.activemq</groupId>
    <artifactId>activemq-spring</artifactId>
    <version>5.10.0</version>
    <type>xsd</type>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>4.1.1.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
  </dependency>
  <dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.0-api</artifactId>
    <version>1.0.1.Final</version>
  </dependency>
  <dependency>
    <groupId>net.rforge</groupId>
    <artifactId>REngine</artifactId>
    <version>0.6-8.1</version>
  </dependency>
  <dependency>
    <groupId>net.rforge</groupId>
    <artifactId>Rserve</artifactId>
    <version>0.6-8.1</version>
  </dependency>
  <dependency>
    <groupId>org.R</groupId>
    <artifactId>RSession</artifactId>
    <version>1.0</version>
    </dependency>
  </dependencies>
</project>

Hibernate DAO (les objets de mappage ont été omis pour plus de clarté, car je ne pense pas qu'ils causent le problème, car l'exception est levée avant qu'aucun d'entre eux ne puisse être utilisé):

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;

import boardwalk.computeServer.data.InterpolationDesiredPoint;
import boardwalk.computeServer.data.InterpolationJob;

public class DbDaoHibernateImpl implements DbDao {

    private final SessionFactory sessionFactory;

    public DbDaoHibernateImpl(SessionFactory sessionFactory){
        // Save the session factory
        this.sessionFactory = sessionFactory;
    }


    @Override
    public InterpolationJob getInterpolationJob(int jobId) {

        // Get the session
        Session s = sessionFactory.getCurrentSession();

        // Load the object from the database and return it
        return (InterpolationJob) s.get(InterpolationJob.class, jobId);

    }

}

Classe principale:

import org.Apache.log4j.Logger;
import org.Apache.xbean.spring.context.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;

import boardwalk.computeServer.dao.DbDao;

public class ComputeServer {

    private static final Logger LOG = Logger.getLogger(ComputeServer.class);

    /**
     * Runs the server
     * @param args none
     */
    public static void main(String[] args) {

        // Create the application context
        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/beans.xml");
    context.registerShutdownHook();

        // Log the server start
        LOG.info("Server has started");

        test(context);
    }


   @Transactional
   public static void test(ClassPathXmlApplicationContext context){
      DbDao dao = (DbDao) context.getBean("dbDao");
      System.err.println(dao.getInterpolationJob(1));
   }

}

Fichier de configuration Spring:

<?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"
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-4.1.xsd
    http://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context-4.1.xsd">

<!-- Load the properties file -->
<context:property-placeholder location="classpath:application.properties" />

<!-- C3PO pooled database connections -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

    <!-- These are C3P0 properties -->
    <property name="acquireIncrement" value="1" />
    <property name="minPoolSize" value="1" />
    <property name="maxPoolSize" value="10" />
</bean>

<!-- Hibernate session factory -->
<bean id="hibernateSessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="boardwalk.computeServer.data" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<!-- The database DAO -->
<bean id="dbDao" class="boardwalk.computeServer.dao.DbDaoHibernateImpl">
    <constructor-arg ref="hibernateSessionFactory" />
</bean>

<!-- The transaction manager -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="hibernateSessionFactory" />
</bean>


<context:annotation-config></context:annotation-config>
</beans>

Je dois noter que le programme fonctionne correctement lorsque je remplace "getCurrentSession ()" par "openSession ()".

Merci d'avance!

12
Ralph

@Transactional sur la méthode test () est inutile, il ne fonctionne que sur le bean géré par ressort. C'est pourquoi il n'y a pas de contexte de transaction.

comme l'a dit @hiimjames, mettez @Transactional sur votre classe ou méthode DAO

20
jpprade

Une autre façon de procéder consiste à exécuter des tests DAO avec l'annotation suivante: @RunWith(SpringJUnit4ClassRunner.class)

De cette façon, l'annotation @ Transactional fonctionnera. Je choisirais d'éviter d'utiliser des transactions au niveau DAO. La transaction est censée se produire au service.

4
borjab