我有两个实体:Question和收藏夹计数器。首次将问题添加到收藏夹时,应创建收藏夹计数器。
考虑一个用例,当两个用户试图同时向收藏夹中添加问题时-当第二个用户调用EntityExistsException
时,这将导致entityManager.persist(counter)
。
但是下面的代码不起作用,因为抛出EntityExistsException
时,容器将事务标记为仅回滚,并且尝试返回getFavoritesCounter(question)
失败,并显示javax.resource.ResourceException: Transaction is not active
@Stateless
public class FavoritesServiceBean implements FavoritesService {
...
public void addToFavorites(Question question) {
FavoritesCounter counter = getCounter(question);
if (counter == null) {
counter = createCounter(question);
}
//increase counter
}
private FavoritesCounter createCounter(Question question) {
try {
FavoritesCounter counter = new FavoritesCounter();
counter.setQuestion(question);
entityManager.persist(counter);
entityManager.flush();
return counter;
} catch (EntityExistsException e) {
return getFavoritesCounter(question);
}
}
private FavoritesCounter getFavoritesCounter(Question question) {
Query counterQuery = entityManager.createQery("SELECT counter FROM FavoritesCounter counter WHERE counter.question = :question");
counterQuery.setParameter("question", question);
List<FavoritesCounter> result = counterQuery.getResultList();
if (result.isEmpty()) return null;
return result.get(0);
}
}
题
@Entity
public class Question implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
//getter and setter for id
}
收藏夹计数器
@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
之后返回已创建的实体的最佳方法是什么? 最佳答案
您可以将createCounter()移到另一个Session 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(),以便容器知道开始新事务。
关于java - 如何正确处理EntityExistsException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3037499/