【发布时间】:2013-05-07 13:44:13
【问题描述】:
问题是在 Spring 托管 bean 中注入 @PersistenceContext 的 EntityManager 不会将实体持久化到数据库中。我尝试在AddDao bean 上使用@Transactional,其中调用了entityManager.persist()(我已启用注释驱动的事务)。
事务从另一个 bean 开始,该 bean 由 Camel 在 Camel Java DSL 中用 .transacted() 实例化。该 bean 有一个 @Autowired 属性,它是 DAO,并具有注入 @PersistenceContext 的 EntityManager。
使用Bitronix作为事务管理器。
Spring xml 配置文件的一部分如下所示:
<bean id="localContainerEntityManagerFactoryBean" depends-on="btmConfig" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="nameFromPersistenceXml"/>
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="packagesToScan" value="package with @Entity POJOs"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration"
class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm" />
</bean>
<!-- create BTM transaction manager -->
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig"
destroy-method="shutdown" />
<!-- Spring JtaTransactionManager -->
<bean id="springTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<tx:annotation-driven transaction-manager="springTransactionManager" />
编辑:在过于简化的版本中,它看起来像这样:
在 Camel Java DSL 中有
from("wsLayer")
.transacted()
.otherProcessing()
.to("bean:addBean?method=addMyEntity")
添加 bean 看起来像这样:
@Component
public class AddBean {
@Autowired
private AddDao addDao;
public void addMyEntity(MyEntity myEntity) {
//other business logic
addDao.persistMyEntity(myEntity);
}
}
@Component
public class AddDao {
@PersistenceContext
private EntityManager entityManager;
//I have tried here
//@Transactional and
//@Transactional(propagation = PropagationType.REQUIRES_NEW)
public void persistMyEntity(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}
从数据库中读取效果很好。
查看数据源:
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
init-method="init" destroy-method="close">
<property name="uniqueName" value="theName" />
<property name="maxPoolSize" ><value>${db.pool.maxSize}</value></property>
<property name="minPoolSize" ><value>${db.pool.minSize}</value></property>
<property name="allowLocalTransactions" ><value>true</value></property>
<property name="automaticEnlistingEnabled" ><value>true</value></property>
<property name="className" ><value>${db.pool.datasource}</value></property>
<property name="driverProperties" ref="databaseProperties" />
</bean>
属性在 Maven 的pom.xml 中设置如下:
db.pool.maxSize=15
db.pool.maxSize=5
db.pool.datasource=org.postgresql.xa.PGXADataSource
【问题讨论】:
-
实际上它不会保留任何域对象,无论是大的还是小的。它将它们持久化到缓存/实体管理器而不是数据库(顺便说一句是 PostgreSQL);在调用
em.persist(entity)和em.contains(entity)之后立即结果为真,但entity实际上并没有持久化到数据库中。我猜这与交易有关。关于链接,对象被正常映射,事务是persistence.xml中的JTA,而不是那里讨论的RESOURCE_LOCAL。
标签: java spring jpa transactions apache-camel