Bonjour,
Je suis actuellement en stage de fin d'études d'ingénieur, et je suis en train de réaliser un site web en Java, avec Tomcat 6.0 et JPA (TopLink). Mon site en est à la phase finale (il est en ligne en accès restreint par mot de passe pour l'instant), et je me trouve soudainement à rencontrer des erreurs avec JPA que je n'avais pas lorsque je travaillais en local ou sur mon serveur de développement. Je précise que je suis novice en Java EE & JPA, j'en connais ce que j'en ai appris à l'école.
Je m'explique : j'ai une classe Resources qui contient un EntityManagerFactory et un EntityManager. Tous deux sont initialisés par une servlet lancée au démarrage du contexte. J'utilise ensuite mes entités comme ça par exemple :
Avec cette architecture, depuis que le site est accessible en ligne, j'ai des exceptions qui surviennent de façon sporadiques (par exemple des "Could not refresh not managed object") alors qu'après redémarrage de Tomcat ça remarche. J'ai aussi des exceptions JPA en rapport avec la base MySQL lorsque le site n'a pas été accédé pendant un long moment (week-end par exemple) de type "Communication failure...".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Resources.getEntityManager().getTransaction().begin(); ... Resources.getEntityManager().getTransaction().commit();
Après m'être documenté un peu sur Internet, je vois que EntityManager n'est pas une classe thread-safe. Je regarde un peu comment il faut faire normalement, et je décide de laisser seulement mon EntityManagerFactory dans ma classe Resources, et de faire avant chaque transaction/requête :
Je me suis dit que ça pourrait résoudre mes problèmes car j'ai lu des documents qui expliquent qu'il faut bien utiliser un EntityManager par transaction, et qu'il faut bien le fermer après.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 EntityManager em = Resources.getEmf().createEntityManager(); em.find(...); em.getTransaction().begin(); ... em.getTransaction().commit(); em.close();
Le problème, maintenant, est qu'en faisant ceci mes transactions n'ont aucun effet sur la base. Quand je modifie un objet que j'ai récupéré grâce à un find, le tout dans une transaction bien sûr, et avec l'EntityManager fermé ensuite, la base reste inchangée. J'ai aussi des persist qui n'ont pas d'effet, mais je crois que c'est parce que je ne le fais pas dans le bon ordre. Je pense qu'il faut que je commence par persister l'objet, et ensuite que je définisse ses propriétés avec ses setters (le tout dans une transaction). Car là souvent je créé mon entité, je lui définis ses propriétés, et ensuite seulement j'ouvre la transaction et je persiste. Je vais creuser pour ça, mais ça ne résoud pas mon problème d'entités non mises à jour dans ma base.
Mon site doit être accessible au public jeudi, et comme vous le voyez, je suis dans la panade...
Mon problème n'est peut-être pas facile à comprendre comme ça, demandez-moi des précisions si besoin.
Merci d'avance.
Partager