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!
@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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With