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

Filed under:
|

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

Related posts about jpa

Related posts about unique-constraint