0 Replies Latest reply on Oct 27, 2008 9:19 AM by Martin Ahrer

    Spring integration: transactional method, read only flag not working

    Martin Ahrer Newbie

      I'm trying to utilize Spring managed transactions using Springs @Transactional annotation. Methods that are supposed to read data only also carry the read only flag.
      In order to test that this is working I created a method that tries to break this.

      It executes a entitymanager.merge() operation. Surprisingly the data is written to the database even though the method is marked read only. Just right after the merge() operation it seems that the hibernate session/persistence context is flushed. As far as I know Spring is setting the flush mode MANUAL for read only marked methods.
      Also I have marked the Seam methods with flush mode MANUAL!

      I'm not sure if I'm doing something fundamentally wrong. I would appreciate any hints on that!

      Here is the hibernate config (from persistence.xml)

      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
      <property name="hibernate.connection.username" value="sa" />
      <property name="hibernate.connection.autocommit" value="false" />
      <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:pac" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
      <property name="hibernate.transaction.manager_lookup_class"
           value="org.hibernate.transaction.JBossTransactionManagerLookup" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.use_sql_comments" value="true" />
      <property name="hibernate.format_sql" value="true" />
      <property name="hibernate.connection.default_schema" value="DBO" />
      <property name="hibernate.transaction.flush_before_completion" value="false"/>

      Seam is configured in components.xml

      <core:init debug="true"  transaction-management-enabled="false" />
      <spring:context-loader config-locations="classpath:/beans/seamContext.xml" />
      <persistence:managed-persistence-context name="entityManager" auto-create="true"
           entity-manager-factory="#{entityManagerFactorySpring}" />
      <transaction:no-transaction />

      So as you see Seam is not responsible for handling transactions at all!

      The spring stuff is configured

      <context:annotation-config />
      <tx:annotation-driven proxy-target-class="true"/>
      <seam:configure-scopes />
      <!-- The entity manager factory that will be used to hand off entity managers to Spring based components-->
      <bean id="entityManagerFactory"
           <property name="persistenceContextName" value="entityManager" />
      <!-- The entity manager factory provided to Seam for creating a seam managed entity manager factory -->
      <bean id="entityManagerFactorySpring"
           p:persistenceUnitName="pac" p:persistenceProviderClass="org.hibernate.ejb.HibernatePersistence">
           <property name="persistenceUnitManager">
                     <property name="persistenceXmlLocations"
                          value="classpath*:META-INF/persistence.xml" />
      <!-- The transaction manager -->
      <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
           <property name="entityManagerFactory" ref="entityManagerFactory" />

      The seam component that invokes the transactional method looks as     

      @Begin(flushMode = FlushModeType.MANUAL, join = false)
      public void create() {
      public String createPersonWithReadOnlyTransaction() {
           return "SUCCESS";

      And the transactional method

      public Person saveWithReadOnlyTransaction(Person person) {
           return getJpaTemplate().merge(person);