私はhibernate3.2.7(3.2.5でも同じ問題)をSpring 3.0.1で使用しており、すべてweblogic10.3とOracle10gデータベースにデプロイされています。私はJTAトランザクション管理を使用しており、トランザクションは分散されています(実際には別のアプリケーションで開始および終了され、このコードはちょうどその中間にあります)。
hibernateで使用される構成は、persistence.xmlで宣言されており、次のとおりです。
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WeblogicTransactionManagerLookup"/>
<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.connection.release_mode" value="auto"/>
トランザクションマネージャーに関するSpring構成は次のとおりです。
<!-- Instructs Spring to perfrom declarative transaction managemenet on annotated classes -->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
<!-- Data about transact manager and session factory -->
<bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
<property name="defaultTimeout" value="${app.transaction.timeOut}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- persistence unit is missing jta data source so that application server is not
creating EntitiyManagerFactory, spring will create its own LocalContainerEntityManagerFactoryBean overriding data source-->
<property name="dataSource" ref="myDataSource"/>
<!-- specific properties like jpa provider and jpa provider properties are in persistance unit -->
<property name="persistenceUnitName" value="my.persistence.unit"/>
</bean>
<!-- define data source in application server -->
<jee:jndi-lookup id="myDataSource" jndi-name="${db.jndiName}"/>
私は次のような更新メソッドを持つ一般的なCrudDaoを使用しています:
public void update(Object entity) {
//entityManager injected by @PersistenceContext
entityManager.merge(entity);
entityManager.flush();
}
public Object getById(Object id, Class entityClass) throws PersistenceException{
return (Object)entityManager.find(entityClass, id);
}
更新:getByIdメソッドを追加しました。
期待どおりに機能しないコードは次のようになります。
MyObject myObj = getMyObjectThroughSomeOneToManyRelation(idOne, idOther);
// till now was null
myObj.setSomeDateAttr(someDate);
genericDao.update(myObj);
MyObject myObjFromDB = genericDao.getById(myObj.getId(), MyObject.class);
その結果、myObj.getSomeDateAttr()を出力すると、someDateの値が返されますが、myObjFromDB.getSomeDateAttr()を出力すると、nullが残ります。
更新方法を次のように変更してみました。
org.hibernate.Session s = (org.hibernate.Session) entityManager.getDelegate();
s.evict(entity);
s.update(entity);
s.flush();
そして、それはまだ機能しません。
hibernateのshow_sqlフラグをオンにすると、フラッシュを実行したり、同じIDのオブジェクトをエンティティマネージャーに照会したりしても、更新が発生しません。選択はすべて表示されます。更新:トランザクションの最後に更新が実際に呼び出され、すべてがデータベースに書き込まれます。ですから、私の問題はトランザクション中の「ちょうど」です。
この問題は、春と休止状態のトランザクションマネージャーの構成に関連している可能性があります。
私はすでに1日半を失ってしまったので、誰かが私を助けてくれることを願っています。