Pourquoi ne nous avez manuellement flush() de l'EntityManager dans une étendue PersistenceContext?
Dans notre application J2EE, nous utilisons un EJB-3 stateful bean pour permettre à l'avant code pour créer, modifier et enregistrer les entités persistantes (géré par JPA-2).
Il ressemble à quelque chose comme ceci:
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEntityController implements Serializable
{
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
private MyEntity current;
public void create()
{
this.current = new MyEntity();
em.persist(this.current);
}
public void load(Long id)
{
this.current = em.find(MyEntity.class, id);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save()
{
em.flush();
}
}
Très important, pour éviter trop tôt s'engage, seul le save()
méthode est à l'intérieur d'une transaction, de sorte que si nous appelons create()
, nous insérez rien dans la base de données.
Curieusement, dans le save()
méthode, nous devons appeler em.flush()
afin de vraiment frapper la base de données. En fait, j'ai essayé et constaté que nous pouvons aussi appeler em.isOpen()
ou em.getFlushMode()
, bien tout ce qui est "em".
Je ne comprends pas ce point. Comme save()
est dans une transaction, j'ai pensé que, à la fin de la méthode, la transaction sera validée, et donc la persistance de l'entité gestionnaire automatiquement supprimées. Pourquoi dois-je rincer manuellement?
Grâce,
Xavier
flush()
. joinTransaction()
devrait être suffisant pour enregistrer vos modifications dans votre méthode.OriginalL'auteur Xavier Portebois | 2011-09-01
Vous devez vous connecter pour publier un commentaire.
À être direct et métal, il n'y aura pas de
javax.transaction.Synchronization
les objets enregistrés pour l'EntityManager en question jusqu'à ce que vous avez réellement utilisation il dans une transaction.Nous en app-serveur-la terre va créer l'un de ces objets pour faire la
flush()
et l'enregistrer avec lejavax.transaction.TransactionSynchronizationRegistry
oujavax.transaction.Transaction
. Ce ne peut pas être fait, sauf s'il existe une transaction active.C'est long et à court de celui-ci.
Oui, un serveur d'application peut très bien garder une liste de ressources, il a donné le stateful bean et auto-inscrire dans chaque transaction stateful bean démarrer ou participer à des. L'inconvénient de cette est qui vous fait perdre la capacité de décider où les choses vont dans lequel les opérations. Peut-être vous avez 2 ou 3 différentes opérations à exécuter sur différentes unités de persistance et de l'agrégation du travail dans votre contexte de persistance Étendue à une partie très précise de la transaction. C'est vraiment un problème de conception et l'application serveur doit laisser de telles décisions à l'application elle-même.
Vous l'utilisez dans une transaction, et nous allons l'inscrire dans la transaction. C'est le contrat de base.
Note de côté, selon la façon dont le sous-jacent EntityManager est manipulé, tout appel persistant à l'EntityManager peut être suffisante pour provoquer une chasse d'eau complet à la fin de la transaction. Certes,
flush()
est la plus directe et plus claire, mais unpersist()
ou même unfind()
pourrait le faire.Citation de JPA2.1 spécification (7.6.4.1 Exigences de Contexte de Persistance de Propagation) pour les non-propagée contexte de persistance:
If the entity manager is invoked within a JTA transaction, the persistence context will be associated with the JTA transaction
.OriginalL'auteur David Blevins
Si vous utilisez contexte de persistance étendue, toutes les opérations sur les entités gérées fait à l'intérieur des non-les méthodes transactionnelles sont en attente pour être écrite à la base de données. Une fois que vous appeler la méthode flush() gestionnaire d'entité dans un contexte de transaction tous en file d'attente les modifications sont écrites dans la base de données. Donc, en d'autres termes, le fait que vous avez une méthode est de ne pas commettre les changements de lui-même lors de la sortie de la méthode (comme dans CMT), mais le rinçage de l'entité gestionnaire de la réalité. Vous pouvez trouver l'explication complète de ce processus ici
OriginalL'auteur Kris
Car il n'y a aucun moyen de savoir "quand" le client est fait avec de la session (extension du champ d'application).
OriginalL'auteur Ravindranath Akila