我正在使用带有 spring 3.0.1 的 hibernate 3.2.7(3.2.5 上的相同问题),全部部署在 weblogic 10.3 和 Oracle 10g 数据库上。我正在使用 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 的对象时,我看不到任何更新。选择都是可见的。更新:在事务结束时,实际上调用了更新并将所有内容写入数据库。所以我的问题是在交易过程中“只是”。
恐怕这个问题可能与 spring 和 hibernate 上的事务管理器的配置有关。
希望有人能帮助我,因为我已经失去了一天半的运气。