2013-05-07 83 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); 
    } 
}