Java LocalContainerEntityManagerFactoryBean中的EntityManager不会将实体持久化到数据库中
问题是在Spring管理的bean中注入了Java LocalContainerEntityManagerFactoryBean中的EntityManager不会将实体持久化到数据库中,java,spring,jpa,transactions,apache-camel,Java,Spring,Jpa,Transactions,Apache Camel,问题是在Spring管理的bean中注入了@PersistenceContext的EntityManager不会将实体持久化到数据库中。我尝试在AddDaobean上使用@Transactional,其中调用了entityManager.persist()(我启用了注释驱动的事务) 事务在另一个bean中开始,该bean由Camel在Camel Java DSL中用.transact()实例化。该bean有一个@Autowired属性,该属性是DAO,并在EntityManager中注入了@Pe
@PersistenceContext
的EntityManager
不会将实体持久化到数据库中。我尝试在AddDao
bean上使用@Transactional
,其中调用了entityManager.persist()
(我启用了注释驱动的事务)
事务在另一个bean中开始,该bean由Camel在Camel Java DSL中用.transact()
实例化。该bean有一个@Autowired
属性,该属性是DAO,并在EntityManager
中注入了@PersistenceContext
作为事务管理器,使用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" />
@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);
}
}
db.pool.maxSize=15
db.pool.maxSize=5
db.pool.datasource=org.postgresql.xa.PGXADataSource
并添加如下所示的bean:
<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" />
@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);
}
}
db.pool.maxSize=15
db.pool.maxSize=5
db.pool.datasource=org.postgresql.xa.PGXADataSource
从数据库中读取数据效果良好
请参阅数据源:
<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>
是否尝试在em.persist(实体)之后执行em.flush()? 根据Java EE的文档: persist(entity):使实例被管理并持久化。 但是 em.flush(entity):将持久性上下文同步到基础数据库 因此,您可以执行以下操作:
em.persist(myEntity);
em.flush();
并检查此更改是否有影响。从给出的有限症状来看,JTA事务似乎没有启动和传播。您的EM可以从DB读取数据,允许对其持久上下文缓存进行数据更改,但决不会写入DB 认为这是一个配置问题,您的@Transaction注释被忽略 我已经启用了注释驱动事务 确保在Spring配置中按如下方式配置:
<tx:annotation-driven transaction-manager="springTransactionManager"/>
因此,根据文档,您必须放置一个描述方法行为的URI,它描述了一个选项“flushOnSend”,也许您必须添加该URI。
它描述了一个使用Hibernate的示例。
还有一个类,它是一个测试,也许你可以使用它来检查你是否通过了;-) 以这种方式尝试@Transactional
@Component
public class AddDao {
@PersistenceContext
private EntityManager entityManager;
@Transactional("BitronixTransactionManager")
public void persistMyEntity(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}
我已经试过了,这没什么区别;我没有试过的是
em.merge(entity)
,我会试一下。它也不能与em.merge(entity)
一起工作,无论是否与em.flush()
一起工作。这正是问题所在。事务应该由Camel创建。除了名称空间之外,还有http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
在xsi:schemaLocation
中。我们不使用Camel-JPA组件,而是使用Bean组件。在Camel Java DSL中,没有从(where.process()[…]到(“jpa:[entityClassName][?options]”)的,而是从(where.transact()[…]到(“bean:addBean?method=addEntity”)
。addBean
有一个addDao
bean,它将@PersistenceContext
注入到实体管理器中。你没有将你试图持久化的实体的代码放在你的帖子中,这可能是一个“大对象”的情况吗?看看这个。希望能有帮助。编辑:我发现了。实际上,它不会持久化任何域对象,无论是大的还是小的。它将它们持久化到缓存/entityManager,但不持久化到数据库(即PostgreSQL btw);在调用em.persist(entity)
和em.contains(entity)
之后,结果为true,但实体
实际上并没有持久化到数据库中。我猜这和交易有关。关于链接,对象被正常映射,事务是persistence.xml中的JTA
,而不是这里讨论的RESOURCE\u LOCAL
。