1

I have seen many questions but all of their solution still not clear. here is my set up my Spring Context 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"
    ..
    ...


    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    ...
    ...

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="entityManagerFactory1"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="byName">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="packagesToScan" value="com.my.dom.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle10gDialect
                </prop>             
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <property name="persistenceUnitName" value="PersistenceUnit1"></property>
    </bean>

    <bean id="EntityManagerFactory2"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="byName">
        <property name="dataSource" ref="myDataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="packagesToScan" value="com.my.dom.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.H2Dialect
                </prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
     ..
     ...     


    <bean id="entityManager1" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory1" />
    </bean>
    <tx:annotation-driven transaction-manager="entityManager1" />

    <bean id="EntityManager2" factory-bean="EntityManagerFactory2" factory-method="createEntityManager" autowire="byName" scope="prototype"/>
    <tx:annotation-driven transaction-manager="EntityManager2" />


    <context:component-scan base-package="com.my.dom" />

    <jpa:repositories base-package="com.my.dom.repository"
        entity-manager-factory-ref="entityManagerFactory"
        transaction-manager-ref="transactionManager" />

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>


</beans>

All data source and other connection beans are in place and working fine.

My DAO code is as follows package com.my.dom.dao;

@Component
public class MyDAOImpl implements MyDAO {

@PersistenceContext(unitName="PersistenceUnit1")
EntityManager entityManager; // this is IAR EntityManager.

@Override
@Transactional
public boolean saveMyGroups(
        List<MyGroups> theGroups) {

    logger.info("Entering method -  saveFuturetheGroups ");
    //entityManager.getTransaction().begin();
    for(MyGroups pg : theGroups){
        MyGroups attachedENtity = entityManager.merge(pg);
        entityManager.persist(pg);
    }
    //entityManager.getTransaction().commit();
    entityManager.flush();
    logger.info("Exiting method -  saveFuturetheGroups ");
    //List<MyGroups> savedEntities = futureProcGrpRepository.save(theGroups);
    return true;
}

}

I have all the cglib and aopalliance1.0.jars in classpath as suggested in Spring+JPA @Transactional not committing

Still my code is not committing the changes to DB. ANy help pointers will be really helpful.

The code shows select and insert sql statements and no exceptions throws but code doesnt commit. Is there any issues in @Transactional annotation?

Can defining multiple entitymanagers be any issues here?


Ok what I have found is that if I use @Transactional(propagation=Propagation.REQUIRES_NEW)

on top of my method it commits the changes !! But as per my under standing the default value for Propagation is 'REQUIRED' which any way will start a new transction and should commit at end? Any pointers I am now really confused!!

Thanks HK

Just a note , I am running this from A Junit test case , is it possible that it is explicitely rolling back the changes? I see something like following in logs

INFO : org.springframework.test.context.transaction.TransactionalTestExecutionListener - Rolled back transaction after test execution for test context [[TestContext@a5503a testClass = ProcessingGroupsTestCase, testInstance = null(com.wellmanage.dos.processingGroups.ProcessingGroupsTestCase), testMethod = testSave@ProcessingGroupsTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1363f5a testClass = ProcessingGroupsTestCase, locations = '{classpath:applicationContext.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]

Thanks HK

3
  • Presume that your Entity class is not defined as insert=false,update=false etc
    – Jacob
    Commented Jun 13, 2013 at 12:02
  • Hi,no such attribute in my entity. Commented Jun 14, 2013 at 3:27
  • is there any error thrown from the transaction block Commented Jun 14, 2013 at 3:43

4 Answers 4

4

Ok Guys!! its all my stupidity.. and I beleive I should admit it. All the time I was running the whole DAO and service through my TestCase and I just overlooked the following in my TestCase.

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

The defaultRollback=true was culprit.

What lessons I have learnt. Never ever overlook any code and always try to find issues from beginning of code.

So to make a Spring work with JPA - Have proper context entries (as in my example) - Use @Transactional as in my DAO.

and you should be all set.

Thanks HK

3

By default, defaultRollback is set you true for junit tests, which means, even if you don't specify @TransactionConfiguration, data updated through junit tests will be rolled back.

Setting defaultRollback=false explicitly will solve this issue.

@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)

0

you are to specifiy your transaction manager on your code

@Transactional("entityManager1")
public boolean saveMyGroups(
2
  • But when I have defined a reference "entityManager" and added persistenceUnit name to it, why do I need to define transactionManager on code? Commented Jun 14, 2013 at 3:28
  • I get following exception when I use entityManager1 in Transactional. "testException = org.springframework.dao.InvalidDataAccessApiUsageException: No matching PlatformTransactionManager bean found for qualifier 'entityManager' - neither qualifier match nor bean name match!; nested exception is java.lang.IllegalStateException: No matching PlatformTransactionManager bean found for qualifier 'entityManager1' - neither qualifier match nor bean name match!, ......'{classpath:applicationContext.xml}', classes = '{}', activeProfiles = '{}', contextLoader = '...DelegatingSmartContextLoader']]]" Commented Jun 14, 2013 at 3:33
0

In my case, you just don't want to put @Transactional annotation on the test itself (or the class it's in) and it will solve the issue without having to include:

@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)

which could make unit-testing difficult and is "true" by default for a good reason.

So just make your controller-layer methods @Transactional and do not do this on the tests - they will see modified data then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.