2010-06-14 160 views
2

我有兩個實體:Question和FavoritesCounter。 FavoritesCounter應該在第一次將問題添加到收藏夾時創建。如何正確處理EntityExistsException?

考慮一個用例,當兩個用戶試圖同時添加一個問題到收藏夾 - 當第二個用戶調用entityManager.persist(counter)時,這將導致EntityExistsException

但低於代碼不起作用,因爲當EntityExistsException被拋出時,容器標記事務的回滾並試圖返回getFavoritesCounter(question)失敗javax.resource.ResourceException: Transaction is not active

問題

@Entity 
public class Question implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    //getter and setter for id 

} 

Favo ritesCounter

@Entity 
public class FavoritesCounter implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne 
    @Column(unique = true) 
    private Question question; 

    //getter and setter 

} 

什麼是EntityExistsException後返回已經創建實體的最好方法?

回答

2

,您可以移動createCounter()到另一個會話Bean和標記與@TransactionAttribute(REQUIRES_NEW)

或者你可以移動createCounter()來FavoritesServiceBean(還要確保您添加@TransactionAttribute(REQUIRES_NEW)註解)的本地接口的方法,並調用它作爲如下:

@Stateless 
public class FavoritesServiceBean implements FavoritesService 
{ 

    ... 
    @Resource 
    protected SessionContext sessionContext; 

    public void addToFavorites(Question question) 
    { 
     FavoritesCounter counter = getCounter(question); 
     if (counter == null) { 
      counter = sessionContext.getBusinessObject(FavoritesService.class) 
            .createCounter(question); 
     } 
     //increase counter 
    } 

    @TransactionAttribute(REQUIRES_NEW) 
    public FavoritesCounter createCounter(Question question) 
    { 
     ... 
    } 
    ... 
} 

你需要這樣的容器知道要開始一個新的事務都要經過業務/本地接口,而調用createCounter()直接。

+0

謝謝,它的工作原理! – yatskevich 2010-06-15 11:55:23