私はアプリケーションを前方に移動しようとしています。現在、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
GlassFishは通常、HibernateではなくEclipseLinkを使用します。 GlassFishでHibernateをどのように統合したのでしょうか?その統合がおそらく原因でしょうか? –
EARに追加しました。統合は問題になるかもしれないが、そうであってはならない。 GF3ではそうではありませんでした。 Hibernateには、Glassfishの特定の実装を備えた戦略セレクタがあります。 Wildfly 9にデプロイされた同じEARがトランザクションをロールバックします。したがって、問題はHibernateの "Glassfish oriented"クラスまたはGlassfish自体にある可能性があります。 EclipseLinkのような別のJPA実装への移行は、私たちの選択肢ではありません。 –