3

问题是 Spring 托管 bean 中的EntityManager注入@PersistenceContext不会将实体持久化到数据库中。我已经尝试@Transactional在调用的AddDaobean上使用entityManager.persist()(我已经启用了注释驱动的事务)。

事务从另一个 bean 开始,该 bean 由 Camel.transacted()在 Camel Java DSL 中实例化。该 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" />

编辑:在一个过于简化的版本中,它看起来像这样:

在 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
4

4 回答 4

2

您是否尝试在 em.persist(entity) 之后执行 em.flush()?根据 Java EE 的文档:

em.persist(entity):使一个实例被管理和持久化。但是 em.flush(entity):将持久化上下文同步到底层数据库。

因此,您可以执行以下操作:

em.persist(myEntity);
em.flush();

并检查此更改是否有所作为。

于 2013-05-09T21:45:47.220 回答
1

从给出的有限症状来看,似乎 JTA 事务没有被启动和传播。您的 EM 在某种程度上可以正常工作 - 从数据库读取,允许针对其持久上下文缓存进行数据更改,但从不写入数据库。

认为这是一个配置问题,您的 @Transaction 注释被忽略了。

我启用了注释驱动的事务。

确保它在您的 Spring 配置中配置如下:

<tx:annotation-driven transaction-manager="springTransactionManager"/>

在哪里:

xmlns:tx="http://www.springframework.org/schema/tx"
于 2013-05-10T03:19:29.127 回答
1

因此,根据apache camel jpa文档,您必须放置一个描述方法行为的 URI,它描述了一个选项“flushOnSend”,也许您必须添加该 URI。 这里它描述了一个 Hibernate 的例子。这里是一个测试类,也许你可以使用它并检查你是否没有通过任何;-)

于 2013-05-10T14:22:05.000 回答
1

以这种方式尝试@Transactional

@Component
public class AddDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional("BitronixTransactionManager")
    public void persistMyEntity(MyEntity myEntity) {
        entityManager.persist(myEntity);
    }
}
于 2013-05-17T06:33:41.777 回答