1

So I thoroughly went through Get is not valid without active transaction and know I don't have the problem of not autowiring the SessionFactory and have followed best practices but still am encountering this exception:

org.hibernate.HibernateException: save is not valid without active transaction
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
    at com.sun.proxy.$Proxy31.save(Unknown Source)
    at com.bms.dao.DemandManageDAOImpl.save(DemandManageDAOImpl.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy29.save(Unknown Source)
    at com.bms.service.DemandServiceImpl.createDemand(DemandServiceImpl.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy30.createDemand(Unknown Source)
    at com.bms.dao.DemandManageDAO_UT.testCreateDemand(DemandManageDAO_UT.java:69)

Which I will try to include all the necessary config and code which is spread over multiple files. Sorry for all the files and thank you in advance. This is Java 1.7, Spring 4.0.2.RELEASE, Hibernate 4.3.5.Final

Seems like this was routine with previous versions. I can get around this by getting a session and beginning a transaction but I don't want to do that.

context: applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    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-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- Database Configuration -->
    <import resource="classpath:database/hibernate.xml"/>

    <!-- Auto scan the components -->
    <context:component-scan base-package="com.bms" />

    <tx:annotation-driven/>
    <bean id="demandManageDao" class="com.bms.dao.DemandManageDAOImpl"></bean>
    <bean id="demandService" class="com.bms.service.DemandServiceImpl"> </bean> 
</beans>

hibernate.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <import resource="classpath:database/dataSource.xml" />

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>database/database.${demandEnv}.properties</value>
        </property>
    </bean>
    <!-- Hibernate Session Factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.bms.demand.domain.data</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.autocommit">true</prop>
                <prop key="hibernate.current_session_context_class">thread</prop> 
            </props>
        </property>
    </bean>
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 
</beans>

datasource.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
            <value>database/database.${demandEnv}.properties</value>
    </property>
</bean>
 <!-- HSQLDB Data Source -->        

  <bean id="dataSource" 
         class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>
</beans>

test file:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@TransactionConfiguration(transactionManager = "transactionManager",defaultRollback=true)
@Transactional
public class DemandManageDAO_UT {

    private static ApplicationContext context;
    private SessionFactory sessionFactory;
    private DemandManageDAO demandManageDAO;
    private DemandService demandService;

    @BeforeClass
    public static void setUpClass(){
        context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    }

    @Before
    public void setUp() throws Exception {
        demandManageDAO = (DemandManageDAO)context.getBean("demandManageDao");
        demandService = (DemandService)context.getBean("demandService");
        sessionFactory = (SessionFactory)context.getBean("sessionFactory");
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testCreateDemand() throws Exception {
        Demand myDemand2 = new Demand();
        myDemand2.setId(10L);
        myDemand2.setDescription("text");
        myDemand2.setMonths(1);
        Calendar calendar = Calendar.getInstance();
        calendar.set(2000, 7, 4);
        myDemand2.setStartDate(calendar.getTime());
        Availibility availibility = new Availibility();
        availibility.setId(2L);
        availibility.setMonth(calendar.getTime());
        availibility.setPercentage(new Integer(50));
        availibility.setResourceName("text");
        myDemand2.addAvailibility(availibility);
        Long perId = demandService.createDemand(myDemand2);
        assertThat(perId,is(myDemand2.getId()));
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Availibility sessionObject = (Availibility) session.get(Availibility.class, 2L);
        assertThat(sessionObject.getResourceName(),is("text"));
    }
}

serviceImpl

@Component
public class DemandServiceImpl implements DemandService {

    @Autowired
    DemandManageDAO demandManageDao;

    public void setDemandManageDao(DemandManageDAO demandManageDAO) {
        this.demandManageDao = demandManageDAO;
    }

    @Override
    @Transactional
    public Long createDemand(Demand myDemand2) throws Exception {
        return demandManageDao.save(myDemand2);
    }
}

the DAO

@Repository
public class DemandManageDAOImpl implements DemandManageDAO {
    @Autowired
    SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    @Override
    public Long save(Demand myDemand) throws Exception {
        return (Long) getCurrectSession().save(myDemand);   
    }

    private Session getCurrectSession() {
        return getSessionFactory().getCurrentSession();
    }
}
Community
  • 1
  • 1
Michael Sampson
  • 369
  • 1
  • 6
  • 19
  • 1
    See http://stackoverflow.com/questions/4293098/how-to-integrate-spring-with-hibernate-session-and-transaction-management – axtavt Jun 23 '14 at 19:15
  • Got it. Actually the post I linked to did mention to use autowire to get a session factory. That and get rid of the current session context thread setting. That and pay attention on the stack trace which transaction boundary is causing the was it no active hibernate session or something. – Michael Sampson Jun 24 '14 at 13:06

1 Answers1

1

You can't use auto-commit with transactions, the connections need to be managed by the Transaction Manager instead, so remove these line:

<prop key="hibernate.connection.autocommit">true</prop>

Also you might want to add:

<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property><prop
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911