2010-06-14 6 views
2

J'ai deux entités: Question et FavoritesCounter. FavoritesCounter doit être créé lorsque la question est ajoutée aux favoris pour la première fois.Comment gérer EntityExistsException correctement?

Considérons un cas d'utilisation lorsque deux utilisateurs tentent d'ajouter simultanément une question aux favoris - cela provoque EntityExistsException lorsque entityManager.persist(counter) est appelée pour le deuxième utilisateur.

Mais le code ci-dessous ne fonctionne pas, parce que quand EntityExistsException est jeté, le conteneur marque transaction rollback seulement et tenter de revenir getFavoritesCounter(question) échoue avec javax.resource.ResourceException: Transaction is not active

Question

@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 

} 

Quelle est la meilleure façon de revenir entité déjà créée après EntityExistsException?

Répondre

2

Vous pouvez déplacer createCounter() à une autre session Bean et marquer cette méthode avec @TransactionAttribute(REQUIRES_NEW)

Alternativement, vous pouvez déplacer createCounter() à l'interface locale de FavoritesServiceBean (également vous assurer d'ajouter l'annotation @TransactionAttribute(REQUIRES_NEW)) et l'appeler comme suit:

@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) 
    { 
     ... 
    } 
    ... 
} 

Vous devez passer par l'interface d'affaires/local plutôt d'appeler createCounter() directement si le conteneur sait commencer une nouvelle transaction.

+0

merci, ça marche! – yatskevich

Questions connexes