问题是在Spring托管bean中注入EntityManager
的{{1}}不会将实体持久存储到数据库中。我尝试在@PersistenceContext
bean上使用@Transactional
,其中AddDao
被调用(我启用了注释驱动的事务)。
事务开始于另一个bean,Camel在Camel Java DSL中用entityManager.persist()
实例化。该bean具有.transacted()
属性,该属性是DAO并且@Autowired
注入了EntityManager
。
使用事务管理器Bitronix。
Spring xml配置文件的一部分如下所示:
@PersistenceContext
编辑:在过度简化的版本中,它看起来像这样:
在Camel Java DSL中有
<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" />
添加bean看起来像这样:
from("wsLayer")
.transacted()
.otherProcessing()
.to("bean:addBean?method=addMyEntity")
从数据库中读取效果很好。
查看数据来源:
@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);
}
}
其中属性在Maven的<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>
中设置如下:
pom.xml
答案 0 :(得分:2)
您是否曾尝试在em.persist(实体)之后执行em.flush()? 根据Java EE的文档:
em.persist(entity):使实例成为托管和持久的。 但 em.flush(entity):将持久化上下文与底层数据库同步。
所以,你可以这样做:
em.persist(myEntity);
em.flush();
并检查此更改是否有所作为。
答案 1 :(得分:1)
从给出的有限症状来看,JTA事务似乎没有被启动和传播。你的EM可以正常工作 - 从数据库读取,允许数据更改它的持久上下文缓存,但从不写入数据库。
认为这是一个配置问题,你的@Transaction注释被忽略了。
我启用了注释驱动的交易。
确保在Spring配置中配置如下:
<tx:annotation-driven transaction-manager="springTransactionManager"/>
其中:
xmlns:tx="http://www.springframework.org/schema/tx"
答案 2 :(得分:1)
因此,根据apache camel jpa文档,您必须放置一个描述方法行为的URI,它描述了一个选项“flushOnSend”,您可能需要添加该URI。 Here它描述了一个Hibernate的例子。 here这是一个测试类,也许你可以使用它并检查你是否通过了它; - )
答案 3 :(得分:1)
以这种方式尝试@Transactional
@Component
public class AddDao {
@PersistenceContext
private EntityManager entityManager;
@Transactional("BitronixTransactionManager")
public void persistMyEntity(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}