13

I have been having a similar problem as many people have been having, but I can't seem to figure out what is going wrong in my specific case. I am making a simple database call to test the database connection, and Hibernate is throwing the following exception:

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)

Here is the relevant code and configuration:

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 (mapping objects have been omitted for clarity, as I don't think they are causing the issue, as the exception is being thrown before any of them can be used):

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

    }

}

Main class:

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

}

Spring configuration file:

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

I should note that the program runs fine when I substitute "getCurrentSession()" with "openSession()".

Thank you in advance!

2

2 Answers 2

21

@Transactional on the test() method is useless, it only works on spring managed bean. That is why there is no transaction context.

as @hiimjames said put @Transactional on your DAO class or method

1
  • @borjab's answer below should also be considered in case you don't want to modify your DAO to explicitly being a transaction
    – jlb
    Commented Jan 9, 2017 at 0:25
6

Another way to do this is to run DAO tests with the following annotation: @RunWith(SpringJUnit4ClassRunner.class)

This way the @Transactional annotation will work. I would choose to avoid using transactions at the DAO level. The transaction is supposed to happend at the service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.