如何在另一个事务中提交JPA实体

时间:2015-05-26 13:39:41

标签: jpa ejb

我有一个关注实体:

@Entity
public class Entity1
{
    @Id
    private Long id;
    private String name;
    private String state;

    @Version
    private Long version;
    ... getter and setter
}

和impl业务的多个EJB:

@Stateless
public class EntityDao{
    @PersistenceContext(unitName="")
    private EntityManager em;

    @TransactionAttribute(REQUIRES_NEW)
    public void createEntity1(Entity1 e)
    {
        e.status = "start";
        em.persist(e);
    }

    @TransactionAttribute(REQUIRES_NEW)
    public void changeToTimeout(Entity1 e)
    {
        e.status = "timeout";
        em.merge(e);
    }
}

@Stateless
public class MyService
{

    @EJB
    EntityDao dao;

    @EJB
    MyService2 ms2;

    @PersistenceContext(unitName="")
    private EntityManager em;

    public void doWork()
    {
       Entity1 e = new Entity1();
       dao.createEntity1(e);
       e = em.find(Entity1.class, e.getId());
       em.refresh(e);
       ms2.handle(e);
    }
}

@Stateless
public class MyService2
{
    @EJB
    EntityDao dao;

    public void handle(Entity1 e)
    {
       e.name = "M";
       dao.changeToTimeout(e);
... and other statement that effected on e object
    }
 }

在这种状态下如果在调用dao.changeToTimeout()之前,对象版本发生了变化和增加,我得到OptimisticException,如果在changeToTimeout()中首先查找对象然后更改了status字段,则忽略另一个事务中的更改因为此事务没有知道另一个交易JPA背景。

有没有办法加入两个JPA上下文?

1 个答案:

答案 0 :(得分:0)

将交易属性类型更改为必需。

@TransactionAttribute(TransactionAttributeType.REQUIRED)

它将加入客户端事务上下文。

现在您拥有'REQUIRES_NEW',意味着始终以新的交易环境开始。