2016-12-21 5 views
0

私はアプリケーションを前方に移動しようとしています。現在、Glassfish 3、JAVA EE 6で動作し、JPA実装としてHibernate 3を使用しています。 私はトランザクションで問題が発生したことを示す例を書いています。いくつかの状況では、アプリケーションは手動でエンティティマネージャのflush()メソッドを呼び出す必要があります。しかし、JTA環境であっても、flush()は基底のデータベースに対して物理的なコミットを引き起こします(ojdbc6.jar JDBCドライバを使用してOracle X/XIに接続しています)。これは、JDBCトランザクションがJTAトランザクションに参加する必要があるため、期待される動作ではありません。 flush()の後にEJBによって例外が発生した場合は、フラッシュされたデータをロールバックする必要があります。 Hibernate 3ではすべてが完全に機能します。 Hibernate 4.3.5ではそれはありません。私が見つけたのHibernate 4.3コードをデバッグflush()を手動で呼び出すと、Glassfish 4のHibernate 4/Hibernate 5とのJTAトランザクションでJDBCトランザクションに参加できません

この

package org.hibernate.jpa.internal.EntityManagerImpl 

      @Override 
      protected Session internalGetSession() { 
          if (session == null) { 
             ... 
             SessionBuilderImplementor sessionBuilder = internalGetEntityManagerFactory().getSessionFactory().withOptions(); 

--->>>>>>   sessionBuilder.autoJoinTransactions(getTransactionType() != PersistenceUnitTransactionType.JTA); <<<<<<----- 

             session = sessionBuilder.openSession(); 
          } 
          return session; 
      } 

これは、このブロックに入力し、JTAとの同期をスキップするorg.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.attemptToRegisterJtaSync()メソッドをリードプラットフォーム..

.... 
      final JoinStatus joinStatus = currentHibernateTransaction.getJoinStatus(); 
      if (joinStatus != JoinStatus.JOINED) { 
             // the transaction is not (yet) joined, see if we should join... 
---->>>>>   if (!transactionContext.shouldAutoJoinTransaction()) { <<<<<<---- 
                 // we are supposed to not auto join transactions; if the transaction is not marked for join 
                 // we cannot go any further in attempting to join (register sync). 
                 if (joinStatus != JoinStatus.MARKED_FOR_JOINED) { 
                     if (isDebugging) { 
                        LOG.debug("Skipping JTA sync registration due to auto join checking"); 
                     } 
                     return; 
                 } 
             } 
          } 

は、私は、Hibernate 5デバッグしようとしましたが、ここでAutoJoinTransactionの問題は、トランザクションコードのほとんどが書き換えられている、姿を消しました。いずれにせよ、flush()の問題は依然として存在します。

私はそれを実証する小さな例を書いた。

@Stateless 
public class BaseServicesAdapterImpl implements BaseServicesAdapterInterface { 

    @PersistenceContext 
    protected EntityManager em; 

    @Resource SessionContext sessionContext; 

    public EntityManager getEm() { 
     return em; 
    } 

    public void setEm(EntityManager em) { 
     this.em = em; 
    } 

    @Override 
    public String test() { 
     persistEntityAndFlush(); 
     return "finished"; 
    } 


    private void persistEntityAndFlush() { 
     persistEntityAndFlush("TST", new Integer(5), new Long(-1), new Long(-1), 
       new Date(), "", null, new Date(), new Integer(10), "test transaction", 
       null, null, null, "");  
    } 


    private Long persistEntityAndFlush(String tipoProcesso, Integer tpEntita, Long idEntita, Long progr, 
      Date date, String stato, String subStato, Date dtStato, Integer ggTimer, 
      String descrizione, String idPrcPerif1, String idPrcPerif2, String idPrcPerif3, String chiave1) { 
      Long idProcesso = 0L; 

      TestEntity testEntity = new TestEntity(); 
      testEntity.setTpEntita(tpEntita); 
      testEntity.setIdEntita(idEntita); 
      testEntity.setIdProcesso(idProcesso); 

      //..... 

      getEm().persist(testEntity); 

      //***** THIS FLUSH COMMITS THE DATA ***** 
      getEm().flush(); 

      throw new RuntimeException("Too late?"); 
    } 


} 

これはperstistence.xmlファイル

<?xml version="1.0" encoding="UTF-8"?> 
<persistence 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_1_0.xsd" 
    version="1.0"> 

    <persistence-unit name="test_pu" transaction-type="JTA"> 
     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
     <jta-data-source>dsName</jta-data-source> 
     <properties> 
      <property name="hibernate.hbm2ddl.auto" value="none" /> 
      <property name="hibernate.show_sql" value="true" /> 
      <property name="hibernate.format_sql" value="false" /> 
      <property name="hibernate.use_sql_comments" value="false" /> 
      <property name="hibernate.generate_statistics" value="false" /> 
      <property name="hibernate.ejb.metamodel.generation" value="disabled" /> 

      <!-- removing this does not affect anything --> 
      <property name="hibernate.connection.release_mode" value="after_transaction" /> 

      <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />    
     </properties> 
    </persistence-unit> 
</persistence> 

私は何をしないのですのですか? 助けていただければ幸いです。事前に おかげで、

デビッドObber

+0

GlassFishは通常、HibernateではなくEclipseLinkを使用します。 GlassFishでHibernateをどのように統合したのでしょうか?その統合がおそらく原因でしょうか? –

+0

EARに追加しました。統合は問題になるかもしれないが、そうであってはならない。 GF3ではそうではありませんでした。 Hibernateには、Glassfishの特定の実装を備えた戦略セレクタがあります。 Wildfly 9にデプロイされた同じEARがトランザクションをロールバックします。したがって、問題はHibernateの "Glassfish oriented"クラスまたはGlassfish自体にある可能性があります。 EclipseLinkのような別のJPA実装への移行は、私たちの選択肢ではありません。 –

答えて

0

まあ、私は、このモードでは、トランザクションを管理する責任は、コンテナ管理のトランザクション(CMT)ですあなたはEJB、EJBのトランザクションのデフォルトモードを使用していることがわかりEJBコンテナから取得します。これは、CMTモードで各Session Beansメソッドのトランザクション属性に従ってオープン、クローズ、アボートします。

@TransactionManagement (TransactionManagementType . CONTAINER) 
public class YourClass 

Beanのトランザクションの管理を参照してください - BMT

BMTを使用して
@TransactionManagement (TransactionManagementType . BEAN) 
public class YouClass 

を、あなたが開くことができ、近い、など中止、および責任があるアプリケーションから

+0

これは重要なことではありません。コンテナは、トランザクションがロールバックされたときに、管理対象のトランザクションがデータをコミットしないようにする必要があります。 –

1

私のミス!私はresource-ref要素を見逃しました! これがなぜ問題を引き起こすのかはわかりませんが、それを加えて解決しました。

<servers> 
    <server config-ref="server-config" name="server"> 
    <!-- WITH THE FOLLOWING LINE THE TRANSACTION PROBLEM DISAPPEARS --> 
     <resource-ref ref="MyDataSource"></resource-ref> 
    </server> 
    </servers>`` 
関連する問題