How to handle EntityExistsException properly?
Posted
by Ivan Yatskevich
on Stack Overflow
See other posts from Stack Overflow
or by Ivan Yatskevich
Published on 2010-06-14T13:19:15Z
Indexed on
2010/06/14
13:22 UTC
Read the original article
Hit count: 538
jpa
|unique-constraint
I have two entities: Question and FavoritesCounter. FavoritesCounter should be created when the question is added to favorites for the first time.
Consider a use case when two users tries to add a question to favorites simultaneously - this will cause EntityExistsException
when entityManager.persist(counter)
is called for the second user.
But the code below doesn't work, because when EntityExistsException
is thrown, container marks transaction as rollback only and attempt to return getFavoritesCounter(question)
fails with 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);
}
}
Question
@Entity
public class Question implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
//getter and setter for id
}
FavoritesCounter
@Entity
public class FavoritesCounter implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne
@Column(unique = true)
private Question question;
//getter and setter
}
What is the best way to handle such a situation - return already created entity after EntityExistsException
?
© Stack Overflow or respective owner