2013-05-07 34 views
3

问题是,在Spring托管bean中注入@PersistenceContextEntityManager不会将实体持久存储到数据库。我尝试在AddDao bean上使用@Transactional,其中entityManager.persist()被调用(我启用了注释驱动事务)。LocalContainerEntityManagerFactoryBean的EntityManager不会将实体持久存储到数据库中

事务从Camel Java DSL中的.transacted()实例化的另一个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" /> 

编辑:在一个过分简化的版本,它看起来是这样的:

在骆驼的Java DSL有

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); 
    } 
} 

从数据库读取效果很好。

查看资料来源:

<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 
+0

你没有把代码你试图坚持在你的文章中的实体,它可能是一个“大对象”的情况? 选中此链接(http://www.postgresql.org/docs/8.4/interactive/largeobjects.html)。希望能帮助到你。编辑:我发现[这](http://stackoverflow.com/questions/12362531/how-do-you-auto-commit-an-sql-server-transaction-in-jpa)。 – n3k0 2013-05-09 21:16:05

+0

实际上,它不会持续任何域对象,既不是大也不是小对象。它将它们保存到缓存/实体管理器中,但不保存到数据库(这是PostgreSQL btw);在调用'em.persist(entity)'后立即在'em.contains(entity)'之后,结果是真的,但是'entity'实际上并没有持久化到数据库。我猜这与交易有关。关于链接,对象通常被映射,事务在'persistence.xml'中是'JTA',而不是在那里讨论的'RESOURCE_LOCAL'。 – m3th0dman 2013-05-09 21:25:20

回答

2

你有没有试图执行em.persist后em.flush()(实体)? 根据Java EE文档:

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

所以,你可以这样做:

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

,并检查是否这种变化有所作为。

+0

我试过了,这没有什么区别;我没有尝试过的是'em.merge(entity)',我会尝试。 – m3th0dman 2013-05-10 06:58:48

+0

之后,它也不适用'em.merge(entity)'有或没有'em.flush()'。 – m3th0dman 2013-05-10 14:42:05

1

从有限的症状给出,似乎JTA事务没有被启动和传播。你的EM可以正常工作 - 从数据库中读取数据,允许数据改变它的持久性上下文缓存,但不会写入数据库。

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

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

确保它的配置为您的Spring配置如下:

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

其中:

xmlns:tx="http://www.springframework.org/schema/tx" 
+0

这正是它的问题。交易应该由骆驼创造。除了命名空间之外,在'xsi:schemaLocation'中有'http://www.springframework.org/schema/tx http:// www.springframework.org/schema/tx/spring-tx-2.0.xsd'。 – m3th0dman 2013-05-10 07:01:10

1

所以,用apache camel jpa文件根据,你必须把它描述的URI你的方法的行为,它描述了一个选项“flushOnSend”,也许你必须添加该URI。 Here它描述了一个Hibernate的例子。 而​​一类,它是一个测试,也许你可以使用它,请检查您是否未能通过任何;-)

+0

我们不使用骆驼JPA组件,而是使用Bean组件。在Camel Java DSL中,不存在from(wherever).process()[...](“jpa:[entityClassName] [?options]”),而是from(wherever).transacted()。 [...]至( “豆:addBean方法= addEntity”)。'。 'addBean'具有'@ Autowired'这个'addDao' bean,它已经向'EntityManager'注入了'@ PersistenceContext'。 – m3th0dman 2013-05-10 14:40:22

1

尝试@Transactional这样

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

    @Transactional("BitronixTransactionManager") 
    public void persistMyEntity(MyEntity myEntity) { 
     entityManager.persist(myEntity); 
    } 
} 
相关问题