De plus en plus d’applications utilisent Hibernate. Mais de temps en temps, pour des raisons de performance, on peut être tenté de remplacer les requêtes Hibernate par du SQL. Et là, les choses se gâtent.
Débloque les + belles offres tech en 10 mins
En effet, le cycle de vie d’un objet chargé avec Hibernate est comme suit :
Maintenant où est le problème ? Eh bien, supposons qu’entre l’étape 2 et l’étape 3 l’application fasse une écriture en base sur notre objet, sans passer par Hibernate. Ce dernier ne saura pas qu’il y a eu une mise à jour dans son dos. Dès lors, après que la mise à jour de données a été faite par le SQL, Hibernate va l’écraser au moment du flush() et donc, il n’y a aucun moyen de prédire ce qui va se passer et les données en base seront probablement incohérentes.
Il existe plusieurs moyens de contourner le problème :
Débloque les + belles offres tech en 10 mins
Cet article vous a plu ? Vous aimerez sûrement aussi :
Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.
Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.
Changer d’entreprise, c’est excitant. Nouveau challenge, nouveaux collègues, nouveau café. Mais, bien souvent, on oublie…
Ça n’étonnera personne si nous affirmons que le monde du développement logiciel est en constante…
En Allemagne, le travail en tandem à temps partiel, aussi appelé « jobsharing » est…
On se retrouve comme d'habitude pour le début du classement qcm saison automne ! Mais…
La saison printemps des tests techniques WeLoveDevs s'est terminée le 31 mai, et c'est Axel…
View Comments
Hum l'utilisation d'un champ version devrait normalement régler ce genre de problème non?
Par ailleurs pour moi les problèmes de performance se rencontrent plus généralement à la lecture qu'à l'écriture et on peut demander à la session hibernate (donc passant par le cache) d'executer une SQL query si je me souvient bien.
Cordialement.
Bonjour,
En fait non, quand on demande à la session Hibernate d'exécuter une query SQL, celle-ci l'envoie directement au driver JDBC sans mettre à jour son état interne. La doc ici n'est pas très claire, je vous invite à essayer un exemple simple pour vous en convaincre du type une table avec deux champs, on charge une entité avec Hibernate qu'on met à jour avec une valeur, on met à jour ensuite la table avec du SQL natif en passant par la session et ensuite on flush la session. Contrôlez le résultat, vous risquez d'être surpris.
Il y a qq trucs sur stackoverflow sur le sujet, notamment ceci :
http://stackoverflow.com/questions/15595627/hibernate-query-cache-applicable-for-native-queries
Pour l'utilisation du champ version, l'approche peut fonctionner mais pas dans tous les cas. En effet dans le cas où le premier update en SQL met à jour la version, les données ne seront pas remplacées par du Hibernate. Maintenant cela pose deux problèmes :
1/ La gestion côté Hibernate doit être totalement transactionnelle, ce qui n'est hélas pas toujours le cas dans la vraie vie.
2/ Dans le cas où il y a un mix d'update en SQL et d'update en Hibernate au sein du même thread, on risque tout de même se retrouver avec un truc assez horrible à déboguer, et il faut aussi que le SQL mette à jour la version de manière atomique.
Néanmoins c'est tout de même plus safe que ne rien faire du tout.
Bon après un peu de recherche je viens de trouver ceci :
https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/5/html/Hibernate_Entity_Manager_Reference_Guide/batch.html
"As already discussed, automatic and transparent object/relational mapping is concerned with the management of object state. This implies that the object state is available in memory, hence updating or deleting (using SQL UPDATE and DELETE) data directly in the database will not affect in-memory state"
-> D'où le risque de perte de données avec un update ou un delete en SQL natif.