Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-9883

Inconsistent behavior for LocalContainerEntityManagerFactoryBean for using/not using persistence.xml, with Hibernate4

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 3.1.2
    • Fix Version/s: 3.1.3, 3.2 RC1
    • Component/s: Data:ORM
    • Labels:
      None

      Description

      The finding is triggered by the transaction/auto-flushing problem I encountered and discussed in the reference URL.

      I am using Spring 3.1.2, Hibernate 4.1.6, WebSphere 8

      The symptoms is: If I use LocalContainerEntityManagerFactoryBean (Lemme call it LCEMFB) without persistence.xml, when I am performing transactional actions (e.g. flushing the entity manager (em) ), it complains for no transaction in progress (It seems to me that Hibernate is unable to lookup the transaction). However if I use the traditional way to have a persistence.xml which contains almost identical settings, it works without problem.


      Here is the non-persistence.xml config:

      snippet in app context xml:

      app context xml snippet

       
      <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="jpaPropertyMap">
              <map>
                  <entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
                  <entry key="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform"/>
                  <entry key="hibernate.current_session_context_class" value="jta" />
                  <entry key="hibernate.transaction.flush_before_completion"  value = "true" />
              </map>
          </property>
      </bean>
       

      (No META-INF/persistence.xml)

      Such way to config LCEMFB give me problem of "no transaction in progress", or failed "auto-flushing" (please refer to reference URL for different behavior with different jpaPropertyMap combination)

      -------------

      However, if I switch the whole setting to

      app context xml snippet

       
      <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="persistenceUnitName" value="foobar" />
      </bean>
       

      persistence.xml

       
      <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/fooDs</jta-data-source>
       
              <class>com.foo.FooModel</class>
       
              <properties>
                  <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
                  <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform" />
                  <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>
       


      Though the configuration is almost identical, the "no persistence.xml" way is not giving result as expected.

        Activity

        Hide
        adrianshum Adrian Shum added a comment -

        Just found I missed one line: After I switch to use persistence.xml for configuration, everything works fine, nomore "no transaction in progress", and auto-flushing of Hibernate works fine.

        Show
        adrianshum Adrian Shum added a comment - Just found I missed one line: After I switch to use persistence.xml for configuration, everything works fine, nomore "no transaction in progress", and auto-flushing of Hibernate works fine.
        Hide
        adrianshum Adrian Shum added a comment -

        A further trial-and-error give a clearer picture:

        1) I can move almost all settings from persistence.xml to Spring's config, leaving only the <persistence-unit name="foo" transaction-type"="JTA"> line in persistence.xml. It works fine.

        2) I need to have transaction-type = "JTA" in persistence.xml. Having "RESOURCE_LOCAL" is giving the same error of "no transaction in progress". (Though it works in my previous projects with Spring 2.5 + Hibernate 3 + WebLogic)

        (A wild guess) It seems to be that for the xml-less LocalContainerEntityManagerFactoryBean bootstrapping method, it is making the native entity manager intialized as it is having a persistence.xml with transaction-type as "LOCAL_RESOURCES" (though we haven't declare it anywhere), which caused the problem (at least for the combination of framework/system I am using this time).

        Workaround is to leave persistence.xml in my JAR. However, by doing so, "packagesToScan" become useless (I found it cannot co-exists with persistence.xml).

        Show
        adrianshum Adrian Shum added a comment - A further trial-and-error give a clearer picture: 1) I can move almost all settings from persistence.xml to Spring's config, leaving only the <persistence-unit name="foo" transaction-type"="JTA"> line in persistence.xml. It works fine. 2) I need to have transaction-type = "JTA" in persistence.xml. Having "RESOURCE_LOCAL" is giving the same error of "no transaction in progress". (Though it works in my previous projects with Spring 2.5 + Hibernate 3 + WebLogic) (A wild guess) It seems to be that for the xml-less LocalContainerEntityManagerFactoryBean bootstrapping method, it is making the native entity manager intialized as it is having a persistence.xml with transaction-type as "LOCAL_RESOURCES" (though we haven't declare it anywhere), which caused the problem (at least for the combination of framework/system I am using this time). Workaround is to leave persistence.xml in my JAR. However, by doing so, "packagesToScan" become useless (I found it cannot co-exists with persistence.xml).
        Hide
        juergen.hoeller Juergen Hoeller added a comment -

        I've addressed this through the introduction of a "jtaDataSource" bean property on LocalContainerEntityManagerFactoryBean now, explicitly indicating JTA awareness. Simply using that one instead of "dataSource" should reliably expose transaction type JTA to the persistence provider, even without persistence.xml.

        Juergen

        Show
        juergen.hoeller Juergen Hoeller added a comment - I've addressed this through the introduction of a "jtaDataSource" bean property on LocalContainerEntityManagerFactoryBean now, explicitly indicating JTA awareness. Simply using that one instead of "dataSource" should reliably expose transaction type JTA to the persistence provider, even without persistence.xml. Juergen
        Hide
        lado Vlado Kuruc added a comment -

        Hi,
        is there any difference in setting JTA awareness in this way?
        <property name="jpaPropertyMap">
        <map>
        <entry key="javax.persistence.transactionType" value="JTA" />
        </map>
        </property>

        Show
        lado Vlado Kuruc added a comment - Hi, is there any difference in setting JTA awareness in this way? <property name="jpaPropertyMap"> <map> <entry key="javax.persistence.transactionType" value="JTA" /> </map> </property>
        Hide
        matthias.mueller Matthias Müller added a comment -

        Note:
        Be careful with

        autowire="byType"

        in your context, this may cause that both 'dataSource' and 'jtaDataSource' get wired...which leads to errors in 99.99% of cases.

        Show
        matthias.mueller Matthias Müller added a comment - Note: Be careful with autowire="byType" in your context, this may cause that both 'dataSource' and 'jtaDataSource' get wired...which leads to errors in 99.99% of cases.

          People

          • Assignee:
            juergen.hoeller Juergen Hoeller
            Reporter:
            adrianshum Adrian Shum
            Last updater:
            Matthias Müller
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              5 years, 3 weeks, 2 days ago