2012-01-23 102 views
2

我有一個運行在Websphere內部的應用程序,並且我遇到了持久化JPA實體的問題。Spring,Websphere,JMS和Eclipselink問題

此前,該應用程序是建立與RESOURCE_LOCAL持久單元,與Spring JpaTransactionManager接口,並且該交易是在代碼明確承諾。

TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition()); 
    try { 
    entityManager.persist(someJpaEntity); 
    } 
    catch(Exception exception) { 
    transactionManager.rollback(transactionStatus); 
    throw exception; 
    } 
    try { 
    transactionManager.commit(transactionStatus); 
    } 
    catch(TransactionException exception) { 
    exception 
    } 

我正在對應用程序進行增強,該應用程序允許通過鏈接到Websphere隊列的消息驅動指針進行調用。我可以通過spring設置一個配置,這將允許我的應用程序通過JMS隊列接收消息。 Spring配置是這樣的:

<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="QueueConnectionFactory"/> 
<jee:jndi-lookup id="jmsQueue" jndi-name="DIQueue" /> 

<!-- A dynamic resolver --> 
<bean id="jmsDestResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"/> 

<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> 
    <property name="connectionFactory"> 
     <ref bean="jmsConnectionFactory"/> 
    </property> 
    <property name="destinationResolver"> 
     <ref bean="jmsDestResolver"/> 
    </property> 
</bean> 

<bean id="messageListener" class="my.app.FileMessageListener" /> 

<bean id="exListener" class="my.app.JmsExceptionListener" /> 

<bean id="msgListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="connectionFactory" ref="jmsConnectionFactory" /> 
    <property name="destination" ref="jmsQueue" /> 
    <property name="messageListener" ref="messageListener" /> 
    <property name="transactionManager" ref="transactionManager" /> 
    <property name="taskExecutor" ref="myTaskExecutor" /> 
    <property name="exceptionListener" ref="exListener" /> 
</bean> 

<bean id="myTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> 
    <property name="workManagerName" value="wm/default" /> 
</bean> 

不知道是否有與我的春天設置的一個問題,但我通過我的Active MQ代理接收消息,所以這部分我似乎是用好。

現在,問題是,當我通過JMS接收消息時,我會調用上面的代碼來插入JPA實體。當代碼運行時,我會得到消息「無法在兩階段事務中提交一個階段資源」,或類似的東西。我開始明白的是Spring JpaTransactionManager不支持XA或JTA事務。

所以,我致力於移植到Spring JtaTransactionManager。

我改變了一切我能想到過的使用JTA,這裏是我宣佈我的事務管理器:

<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/> 

更新我的堅持XML:

<persistence-unit name="AppUnit" transaction-type="JTA">   
    <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider> 
    <jta-data-source>java:APPDS</jta-data-source> 

而且還在,沒有什麼工作。我的代碼無一例外地運行,但是沒有任何東西持久存在數據庫中。該消息被從JMS隊列中取出,但沒有數據。

有什麼建議嗎?

回答

1

我終於得到了這個工作,並認爲我會發布答案。

實際上有2件拼圖。

首先,在WebSphere中,你需要到你的應用服務器 - > TransactionService,檢查/啓用「接受啓發式危險」複選框。這肯定有幫助。我正在爲7

的第二件事,就是你必須設置屬性eclipselink.target服務器的持久性單元或您的EntityManagerFactory上。

那第二個項目絕對是訣竅。我測試了財產,沒有它。沒有它,沒有任何東西存在。有了它,一切正常。

這裏是我的EntityManagerFactory,我使用的是屬性佔位符設置eclipselink.target服務器屬性的值:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceUnitName" value="MyUnit" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="databasePlatform">   
       <value>${app.databasePlatform}</value> 
      </property> 
      <property name="showSql"> 
       <value>${app.showSql}</value> 
      </property>    
     </bean> 
    </property> 

<!-- THIS DID THE TRICK --> 
    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="eclipselink.target-server" value="${app.targetServer}"/> 
     </map> 
    </property>  
</bean>