Spring、Websphere、JMS和Eclipselink问题

Spring、Websphere、JMS和Eclipselink问题,spring,jms,websphere,eclipselink,Spring,Jms,Websphere,Eclipselink,我有一个在Websphere内部运行的应用程序,我在持久化JPA实体方面遇到了问题 在此之前,应用程序是使用RESOURCE_本地持久化单元、Spring JpaTransactionManager和在代码中显式提交的事务来设置的 TransactionStatus transactionStatus = transactionManager.getTransaction( new DefaultTransactionDefinition() ); try { entityMa

我有一个在Websphere内部运行的应用程序,我在持久化JPA实体方面遇到了问题

在此之前,应用程序是使用RESOURCE_本地持久化单元、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队列的消息驱动Pojo进行调用。我能够通过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> 

我不确定我的spring设置是否有问题,但我确实通过我的活动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> 

oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
java:APPDS
但仍然没有任何效果。我的代码毫无例外地运行,但没有任何内容被持久化到数据库中。消息已从JMS队列中删除,但没有数据


有什么建议吗?

我终于找到了答案,我想我会发布答案

这个拼图实际上有两块

首先,在Websphere中,您需要转到应用服务器->TransactionService,并选中/启用“接受启发式风险”复选框。这肯定有帮助。我7岁就开始跑步了

第二件事是,必须在持久化单元或EntityManagerFactory上设置eclipselink.target-server属性

第二个项目确实奏效了。我测试了有属性和没有属性。没有它,一切都不会持久。有了它,一切都很好

这是我的EntityManagerFactory,我正在使用属性占位符设置eclipselink.target-server属性的值:

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

${app.databasePlatform}
${app.showSql}