2014-12-06 10 views
12

Mam podobny problem, jak wiele osób, ale nie mogę się domyślić, co dzieje się źle w moim konkretnym przypadku. Robię prostego połączenia z bazą danych w celu przetestowania połączenia z bazą danych i Hibernacja rzuca następujący wyjątek:Hibernate Nie można uzyskać sesji zsynchronizowanej z transakcjami dla bieżącego wątku

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) 

Oto odpowiedni kod i konfiguracja:

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 (obiekty odwzorowania zostały pominięte dla jasności, ponieważ nie sądzę, że powodują problem, ponieważ wyjątek jest zgłaszany, zanim którykolwiek z nich może zostać użyty):

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); 

    } 

} 

główne klasy:

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)); 
    } 

} 

Wiosna plik konfiguracyjny:

<?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> 

Należy zauważyć, że program działa poprawnie, gdy zastąpić "getCurrentSession()" z "openSession()".

Z góry dziękuję!

+2

Nie jestem pewien, czy to pomoże, ale twoje DAO powinno być @Transactional. – hiimjames

+0

Prawdopodobny duplikat [Spring Hibernate - Nie można uzyskać sesji zsynchronizowanej z transakcją dla bieżącego wątku] (http://stackoverflow.com/questions/26203446/spring-hibernate-could-not-obtain-transaction-synchronized-session-for- prąd) – Vadzim

Odpowiedz

19

@ Transakcja w metodzie test() jest bezużyteczna, działa tylko w przypadku fasoli zarządzanej wiosennym. Dlatego nie ma kontekstu transakcji.

jak @hiimjames powiedział umieścić @Transactional na swojej klasy DAO lub metody

+0

Wielkie dzięki! naprawiono problem. – Ralph

+0

dzięki ratownikowi – bynu022

+0

Odpowiedź @ borjab poniżej powinna być również rozważona na wypadek, gdybyś nie chciał modyfikować swojego DAO, aby był jawnie transakcją – jlb

4

Innym sposobem, aby to zrobić, aby uruchomić DAO testy z dopiskiem: @RunWith(SpringJUnit4ClassRunner.class)

ten sposób @Transactional adnotacja praca. Postanowiłbym uniknąć stosowania transakcji na poziomie DAO. Transakcja ma się odbyć w serwisie.