使用Nativequery删除/更新JTA中的记录

时间:2015-05-11 23:08:37

标签: jpa transactions ejb jta

我陷入了困境。

问题是:我必须使用NativeQuery来删除和/或更新JTA上下文(EJB)中的某些DB记录。

我的JPA persistence.xml如下所示:

<persistence-unit name="OzsscJPANBPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/postgres_ozssc</jta-data-source>
    <mapping-file>com/longz/ozssc/model/PostcodeEntity.xml</mapping-file>
    <class>com.longz.ozssc.model.CustomerEntity</class>
 ......

如果我以这种方式使用delete语句:

@Override
public void remove(SmsdOutboxEntity toberemoved){
    em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();

抛出TransactionRequiredException:

root cause

javax.persistence.TransactionRequiredException: 
Exception Description: No transaction is currently active

这样就没有交易存在。

如果我们手动使用交易:

@Override
public void remove(SmsdOutboxEntity toberemoved){
    em.getTransaction().begin();
    em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();
    /*em.flush();*/
    em.getTransaction().commit();

抛出IllegalStateException:

root cause

javax.ejb.EJBException: EJB Exception: ; nested exception is: 
java.lang.IllegalStateException: The method public abstract javax.persistence.EntityTransaction javax.persistence.EntityManager.getTransaction() cannot be invoked in the context of a JTA EntityManager.

似乎我无法手动使用交易,因为JTA会自行管理交易。

所以我的问题是:如何使用Native Query来删除/更新JTA托管上下文中的记录?

请告知。

1 个答案:

答案 0 :(得分:0)

对于JTA,事务由容器提供,您不应自行创建。要在JTA中获取事务,您必须将其作为资源访问:

@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;

@Override
public void remove(SmsdOutboxEntity toberemoved){
   EntityManager em = factory.createEntityManager();
try {
   em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();
   utx.commit();

catch (RuntimeException e) {
    if (utx != null) utx.rollback();
    throw e; // or display error message
}
finally {
    em.close();
}

如果你想省略你自己提交/回滚事务的部分,你需要让你的事务由像EJB3这样的容器管理。为此,您可以使用无状态/有状态的ejb bean。

<强>更新

对于WebLogic,请尝试使用其用户weblogic.transaction.UserTransaction而不是javax.transaction.UserTransaction。正如医生所说:

  

此接口定义特定于WebLogic的扩展   javax.transaction.UserTransaction。