web-dev-qa-db-fra.com

Entitymanager.flush () VS EntityManager.getTransaction (). Commit - Que devrais-je préférer?

Que dois-je préférer lors de la mise à jour de la base de données? Quels sont les avantages et les inconvénients de l’une ou l’autre méthode et quand dois-je utiliser l’une ou l’autre?

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    employee.getPeriod().setEndDate(endDate);
    em.flush();
}

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    em.getTransaction().begin();
    employee.getPeriod().setEndDate(endDate);
    em.getTransaction().commit();
}
43
Rox

Dans votre premier exemple, les modifications apportées aux données sont reflétées dans la base de données après avoir rencontré un vidage, mais elles sont toujours en transaction.

Mais dans le deuxième exemple, vous effectuez une transaction immédiatement. Par conséquent, les modifications sont apportées à la base de données et la transaction se termine également là.

Parfois, un vidage peut être utile pour conserver les données entre la transaction en cours, puis valider les modifications par la suite. Ainsi, vous pouvez également annuler les modifications précédentes s'il se produit un problème par la suite, comme pour l'insertion/la mise à jour par lots.

43
Nayan Wadekar

Vous avez lu le javadoc pour flush et commit et vous savez que flush est uniquement destiné à être utilisé dans une transaction? Il efface (mais ne commet pas), alors que le commit valide des données (évidemment). Ils sont distincts; il n'y a pas de "préférence" à avoir. Le premier exemple est incorrect et devrait donner lieu à une exception lors de l'appel flush (TransactionRequiredException)

14
DataNucleus

Vos deux exemples de code ne persistent pas et ne fusionnent pas l'état de l'entité à écrire dans la base de données.

Je ne pense pas qu'il soit approprié de comparer EntityManager.flush() et EnityManager.EntityTransaction.commit().

flush () DOIT être inclus dans un contexte de transaction et vous ne devez pas le faire explicitement sauf si cela est nécessaire (dans de rares cas), lorsque EntityTransaction.commit () le fait pour vous.

Refer this link Est-il nécessaire d'appeler un flush () (interface JPA) dans cette situation?

Reportez-vous à ce lien Question sur le nettoyage à l'aide de JPA avant l'appel d'une requête pour un scénario utilisant flush () 

3
Ahamed Mustafa M

Je pense que la partie manquante est que flush () ajoute simplement aux sources de données pour être prête à être validée, donne les identifiants réels sans les conserver par défaut.

Donc, si vous avez besoin de flush () pour fonctionner en tant que commit (), vous devez définir le mode flush sur Commit dans EntityManager en:

void setFlushMode(FlushModeType flushMode)
Set the flush mode that applies to all objects contained in the persistence context.

Notez que FlushModeType est une énumération qui a ces deux valeurs:

FlushModeType AUTO (valeur par défaut) Le vidage doit avoir lieu à l'exécution de la requête . Depuis: JPA 1.0 FlushModeType COMMIT Le vidage doit avoir lieu à la transaction commettre. Le fournisseur peut rincer à d'autres moments, mais n'est pas obligé de . Depuis: JPA 1.0

J'espère cette aide

J'irais pour une transaction gérée par conteneur autant que possible. Les transactions gérées par les beans nécessitent généralement beaucoup plus de code, en raison des possibilités d'Exception. En outre, il est plus sujet aux erreurs (annulations, gestion des ressources).

Cela dit, j'utiliserais un vidage après le commit en mode géré par conteneur. De cette façon, je peux attraper les exceptions PersistenceExceptions possibles dans mon module de stockage et les convertir en une exception plus significative pour mon module de cas d'utilisation. Ceci parce que je ne veux pas gérer les exceptions spécifiques au stockage ici, parce que je pourrais échanger le module de stockage contre quelque chose qui n'utilise pas JPA ... qui ne m'est jamais arrivé :)

0
Dormouse