2015-05-26 19 views
0

我有一個後續實體:如何致力於JPA實體在另一個事務

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

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

,多爲EJB的業務IMPL:

@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()首次查找對象然後更改了狀態字段,則忽略另一個事務中的更改,因爲此事務不知道另一個事務JPA上下文。

有沒有辦法加入兩個JPA上下文?

+0

你在'changeToTimeout'方法中嘗試過'em.refresh(e)'嗎?在更改狀態之前。 – DuncanKinnear

+0

我設置了entityManager.setFlushMode(FlushModeType.COMMIT); –

+0

然後因爲同步的默認值是SynchronizationType.SYNCHRONIZED,我發送了entitymanager到新的事務並將我的實體合併到它。在第二個事務提交後,在第一個事務中合併實體並分離它並重新合併。 JPA忽略這項工作來刷新實體更改。 –

回答

0

將交易屬性類型更改爲必需。

@TransactionAttribute(TransactionAttributeType.REQUIRED) 

它將加入客戶端事務上下文。

現在你有'REQUIRES_NEW',表示始終以新的事務上下文開始。

+0

我需要新的事務,如果第一次事務回滾,實體狀態更改爲超時。 –

相關問題