Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Auto Flush not working for Spring 3.1 LocalEntityManagerFactoryBean+Hibernate 4+JTA

  1. #1

    Default Auto Flush not working for Spring 3.1 LocalEntityManagerFactoryBean+Hibernate 4+JTA

    (I am asking the same question at StackOverflow too:
    http://stackoverflow.com/questions/1...bean-hibernate )


    I have did a lot of search on the web and pages like this and this and this mostly suggested for using CMTTransactionFactory. However I am still unable to make it work (I wonder if it is because I am creating a EM using a LocalContainerEntityManagerFactoryBean instead of creating Hibernate session by LocalSessionFactoryBean)

    Here is what I have in my app ctx
    Code:
    <jee:jndi-lookup  id="dataSource" jndi-name="jdbc/fooDs" />
    
    <bean id="transactionManager"
        class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
    
    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
            </bean>
        </property>
        <property name="persistenceUnitName" value="foo" />
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.foo" />
        <!--
          <property name="persistenceXmlLocation" value="classpath:/META-INF/test-persistence.xml" />
         -->
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
                <!--
                  <entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
                  <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
                 -->
                <entry key="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory"/>
                <entry key="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform"/>
                <entry key="hibernate.transaction.flush_before_completion"  value = "true" />
            </map>
        </property>
    </bean>
    (In jpaPropertyMap, I tried to have the two remarked entries and still the same)

    I am making use of Spring Data JPA and after the entity is retrieved, I updated the content. If I am not flushing the repository (which means session/entityManager) manually, it simply discard my changes.

    Can anyone give me some hints on what I have missed in the setting? Is there anything special to notice for using LocalContainerEntityManagerFactoryBean?

    I am using Spring 3.1.2.RELEASE, Hibernate 4.1.6.Final, Websphere 8
    Last edited by adrianshum; Oct 15th, 2012 at 09:11 PM. Reason: add missing links

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    In the snippet you post there is nothing to drive your transaction... There is only a transaction manager (the what) but no where (tx:annotation-driven or some other transaction demarcation).

    Also as you are using the jta.platform property either don't configure the factory_class or make it JtaTransactionFactory...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    I only extract out suspicious snippet to avoid having a huge xml that no one is going to read I am using annotation-driven tx. It seems working fine if I am manually flushing the entity manager (by Spring Data JPA's JpaRepository#flush() )

    Lemme have a try for factory_class change.

    Just to clarify a bit, originally I have only
    <entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtended JTATransactionLookup" />
    <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFac tory"/>
    in the property, and it is not working. However, is it supposed to be fine?

    Thanks

    Quote Originally Posted by Marten Deinum View Post
    In the snippet you post there is nothing to drive your transaction... There is only a transaction manager (the what) but no where (tx:annotation-driven or some other transaction demarcation).

    Also as you are using the jta.platform property either don't configure the factory_class or make it JtaTransactionFactory...

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Well the transaction stuff is basically deprecated in 4.x and you should have enough at only declaring a jta.platform...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5

    Default

    I am wrong on what I have told:
    Only certain combinations of properties in jpaPropertyMap give me "no-auto-flushing" behavior. Other combination simply tell me there is no transaction in progress when I flush.

    Here is the combinations I have tried in jpaPropertyMap:

    Code:
    hibernate.transaction.manager_lookup_class    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    no transaction is in progress




    Code:
    hibernate.transaction.manager_lookup_class    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    hibernate.transaction.factory_class           org.hibernate.transaction.CMTTransactionFactory
    transaction active, manual flush works, auto-flush not working




    Code:
    hibernate.transaction.manager_lookup_class    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    hibernate.transaction.factory_class           org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory
    transaction active, manual flush works, auto-flush not working




    Code:
    hibernate.transaction.manager_lookup_class    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    hibernate.transaction.factory_class           org.hibernate.transaction.JTATransactionFactory
    no transaction is in progress




    Code:
    hibernate.transaction.manager_lookup_class    org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    hibernate.transaction.factory_class           org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory
    no transaction is in progress





    Code:
    hibernate.transaction.jta.platform            org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
    no transaction is in progress





    Code:
    hibernate.transaction.jta.platform            org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
    hibernate.transaction.factory_class           org.hibernate.transaction.CMTTransactionFactory
    no transaction is in progress





    Code:
    hibernate.transaction.jta.platform            org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform
    hibernate.transaction.factory_class           org.hibernate.transaction.JTATransactionFactory
    no transaction is in progress





    In short, no matter I am using jta.platform or manager_lookup_class, JPA/Hibernate seems only be able to pick up the transaction when I am using CMTTransactionFactory. However, auto-flush is still not working.


    My app service look like this:

    Code:
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public class FooServiceImpl implements FooService {
      @Inject
      private FooRepository fooRepo;
    
      public void doSomething() {
        Foo foo = fooRepo.findBySomething(...);
        foo.setBar(...);
        //fooRepo.flush();
      }
    }
    (the line fooRepo.flush() is the place I modify to try manual flushing and auto flushing)

    Repository is making use of Spring Data JPA


    I really have no clues on what else I can try

    Using Spring 3.1.2, Hibernate 4.1.6, Websphere 8

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    We use the exact same combination without problems and we only have a JtaPlatform configured... (The other properties are deprecated). However we don't use Spring Data but plain repositories.

    The no-transaction indicates to me that your @transactional isn't working, can you post a stacktrace in the case of a non-active transaction.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7

    Default

    I have also suspected that my @Transactional is not setup correctly. However when I am using the combination with CMTTransactionFactory as factory_class (i.e. cases with transaction active, but no auto flushing), I intentionally throw an exception and it is rolled back correctly. That seems suggests to me Transaction is correctly setup. Anyway, here you go (something masked in the stacktrace)

    Code:
    com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause spring-rest: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    [.... some deleted]
    	at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
    	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1659)
    Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
    	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321)
    	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:106)
    	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
    	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:91)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy857.flush(Unknown Source)
    	at com.foo.orderservice.app.ccy.impl.CurrencyServiceImpl.activateCurrency(CurrencyServiceImpl.java:79)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    	at java.lang.reflect.Method.invoke(Method.java:611)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    	at org.springframework.transaction.interceptor.TransactionInterceptor$1.doInTransaction(TransactionInterceptor.java:132)
    	at org.springframework.transaction.jta.WebSphereUowTransactionManager$UOWActionAdapter.run(WebSphereUowTransactionManager.java:337)
    	at com.ibm.ws.uow.EmbeddableUOWManagerImpl.runUnderNewUOW(EmbeddableUOWManagerImpl.java:786)
    	at com.ibm.ws.uow.EmbeddableUOWManagerImpl.runUnderUOW(EmbeddableUOWManagerImpl.java:365)
    	at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:281)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:127)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy861.activateCurrency(Unknown Source)
    	at com.foo.orderservice.controller.impl.CurrencyControllerImpl.activateCurrency(CurrencyControllerImpl.java:76)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    	at java.lang.reflect.Method.invoke(Method.java:611)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    	... 34 more
    Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
    	at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:983)
    [... some deleted ...]
    	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    	at $Proxy856.flush(Unknown Source)
    	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:388)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    	at java.lang.reflect.Method.invoke(Method.java:611)
    	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
    	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.transaction.interceptor.TransactionInterceptor$1.doInTransaction(TransactionInterceptor.java:132)
    	at org.springframework.transaction.jta.WebSphereUowTransactionManager$UOWActionAdapter.run(WebSphereUowTransactionManager.java:337)
    	at com.ibm.ws.uow.EmbeddableUOWManagerImpl.runUnderCurrentUOW(EmbeddableUOWManagerImpl.java:971)
    	at com.ibm.ws.uow.EmbeddableUOWManagerImpl.runUnderUOW(EmbeddableUOWManagerImpl.java:369)
    	at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:281)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:127)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    	... 72 more

  8. #8
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Hmm not what I hoped to see ...

    There is a transaction interceptor and that is also working with the TransactionManager. I hoped to see no transaction-interceptor.

    Strange thing is we use the same setup (without spring-data) without any problems. All of our configuration is in persistence.xml

    Spring Configuration
    Code:
    <tx:jta-transaction-manager />
    <tx:annotation-driven proxy-target-class="true" />
    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        <property name="persistenceUnitName" value="foobar" />
    </bean>
    That is all we have, everything else is in the persistence.xml (see below) and it works like a charm.

    Code:
    <persistence version="2.0"
    	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    	<persistence-unit name="foobar" transaction-type="JTA">
     		<provider>org.hibernate.ejb.HibernatePersistence</provider>
    		<jta-data-source>jdbc/ourdatasource</jta-data-source>
    		<properties>
     			<property name="hibernate.dialect" value="org.hibernate.dialect.DB2400Dialect" />
    			<property name="hibernate.transaction.jta.platform" value="our.custom.JtaPlatformImplementation." />
    			<property name="hibernate.current_session_context_class" value="jta"/>
    			<property name="hibernate.transaction.flush_before_completion" value="true"/>
    			<property name="hibernate.connection.release_mode" value="auto"/>
    		</properties>
     	</persistence-unit>	
    </persistence>
    This is all we have and it works...

    Note: Our custom JtaPlatform is nothing more then a wrapper which detects on which server we run and selects the JtaPlatform to use (we have different servers on dev machines and in prod and we didn't want to change the persistence.xml files).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  9. #9

    Default

    Just a little update: I tried to inject EntityManager to my service by @PersistenceContext, and use JPA directly instead of going through Spring Data JPA. Same things happens: Unless I flush the entity manager explicitly, Hibernate is not picking up my updated entity to issue update statement. At least we know the problem has nothing to do with Spring Data

    The biggest difference I can see is I am doing all settings directly at LocalContainerEntityManager, while you are using persistence.xml. Can it be the cause? Lemme try to use persistence.xml tomorrow and have a look

    By the way, what is the container you are using? I wonder if it is a possible cause of problem too
    Last edited by adrianshum; Oct 16th, 2012 at 05:35 AM.

  10. #10
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    What do you mean by container in this case? As mentioned before we use the exact same setup without Spring Data and everything is configured in persistence.xml... Everything else is the same (WAS8, Spring 3.1 etc.)
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •