J'ai une méthode de base que j'écris afin de ne pas répéter la même logique de transaction/session d'hibernation encore et encore. C'est assez simple, mais il y a un problème spécifique que je ne suis pas sûr que l'on puisse résoudre avec cette approche. Imaginez que vous ayez une entité Utilisateur et une entité Autorisation. Si une requête est faite pour enregistrer un utilisateur avec ses permissions correspondantes, alors je pense qu'il serait logique d'effectuer les deux opérations dans une seule transaction, car ne pouvoir sauvegarder qu'une seule de ces entités pourrait être considéré comme une corruption de données. Par exemple, si vous ne sauvegardez pas les autorisations de l'utilisateur, cela justifie une annulation des données utilisateur précédemment insérées. J'ai fait la méthode suivante pour autoriser les opérations de mise en veille prolongée générique qui pourraient fonctionner avec la transaction courante si c'était nécessaire, bien que je pense maintenant que dans sa forme actuelle cela ne fonctionnera pas depuis l'appel de session.beginTransaction(); retournera probablement une nouvelle transaction même si la précédente n'a pas été validée (est-ce le cas?). Supposons que je l'ai modifié pour qu'il renvoie la session et la transaction en cours s'il était spécifié qu'il y aurait plus d'opérations pour la transaction en cours, pensez-vous que cela fonctionnerait? Serait-il souhaitable de faire quelque chose comme ça, ou recommanderiez-vous un changement d'approche? MerciModèle Hibernate pour la réutilisation des transactions
protected <T> void baseOperation(Class<T> entityClass, List<T> instances, BaseHibernateDAO.Operations operation, boolean isLastOperation) throws Exception
{
Session session = null;
Transaction transaction = null;
boolean caughtException = false;
//get session from factory
session = HibernateSessionFactory.getSession();
try
{
//get current transaction
transaction = session.beginTransaction();
for (Object instance : instances) //perform operation on all instances
{
log.debug(String.format("Will perform %s operation on %s instance.", operation.name(), entityClass.getName()));
switch (operation) //perform requested operation
{
case SAVE:
session.save(instance);
break;
case UPDATE:
session.update(instance);
break;
case SAVEORUPDATE:
session.saveOrUpdate(instance);
break;
case DELETE:
session.saveOrUpdate(instance);
break;
}
log.debug(String.format("%s operation on %s instance was succesful.", operation.name(), entityClass.getName()));
}
session.flush(); //synchronize
if (isLastOperation) //if this is the last operation of the transaction
{
transaction.commit();
log.debug("Transaction commited succesfully.");
}
}
catch (Exception e) //error occurred
{
caughtException = true;
//roll-back if transaction exists
if (transaction != null)
{
transaction.rollback();
}
//log and re-throw
log.error("An error occurred during transaction operation.", e);
throw e;
}
finally //cleanup tasks
{
if (isLastOperation || caughtException) //close session if there are no more pending operations or if an error occurred
{
HibernateSessionFactory.closeSession();
}
}
}
Bon point. N'oubliez pas non plus les autres options basées sur les standards d'EJB3 et Seam 3 (basées sur JSR-299). –
Ce n'est pas que j'essaie volontiers de le réécrire, je ne savais pas qu'il existait. Le problème est que je n'ai actuellement pas le temps d'apprendre un autre cadre. J'ai regardé votre exemple et cela semblait assez simple, mais je sais que ce ne sera pas le cas une fois que j'essayerai de l'appliquer à des objets plus complexes. Je n'ai pas encore trouvé un seul exemple qui exécute deux opérations dans une seule transaction, au printemps ou autrement (le plus que j'ai trouvé sont trois points ... impliquant qu'il y aurait plus de code) .Si je ne peux pas vois-le je ne peux pas le comprendre, et donc je préfère le faire moi même si ce n'est pas vrai et vrai – JayPea
Mais de toute façon, merci de me pointer dans cette direction, j'essaierai d'apprendre le printemps quand j'aurai le temps, mais pour l'instant c'est trop risqué d'apprendre quelque chose comme ça au moment du développement :) – JayPea