Obtenir les anciennes données avec JPA
Je me fais vieux données avec JPA, même si je désactive le cache. Je suppose que c'est parce que la ressource est configuré pour être RESOURCE_LOCAL, mais je ne suis pas sûr.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="AppPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.myentities.User</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/mydatabase"/>
<property name="javax.persistence.jdbc.password" value="*****"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="user1"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
Mon code qui est en train de vieillir info sur l'utilisateur:
public List<User> findAll(App app) {
getEntityManager().getTransaction().begin();
Query q = getEntityManager().createQuery("SELECT t1 FROM User t1 WHERE t1.app.idApp=:idApp");
q.setParameter("idApp", app.getIdApp());
getEntityManager().flush();
getEntityManager().getTransaction().commit();
List resultList = q.getResultList();
return resultList;
}
Mon entité:
@Entity
@Table(name = "user")
@Cache (
type=CacheType.NONE
)
public class User implements Serializable {
//some attributtes
}
Quelqu'un a une idée de ce qui se passe?
Mise à JOUR de 1
La commencer, rincer et commettre méthodes ont été seulement des actes de désespoir! Je sais qu'il n'est pas nécessaire.
J'ai oublié de dire quelque chose important: le test-je faire est d'ajouter un enregistrement d'utilisateur direct sur la console de base de données et puis essayer de voir à travers mes webapp, qui est ne pas montrer le nouvel utilisateur. C'est le "vieux de données" je l'ai mentionné, il affiche seulement "des anciens utilisateurs".
J'ai déjà essayé de mettre cela sur persistence.xml et je ne vois pas de différence dans les résultats:
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.size.default" value="0"/>
<property name="eclipselink.cache.type.default" value="None"/>
Donc, c'est autre chose...
- 1) Vous n'avez pas besoin de démarrer/chasse/de commettre l'une transaction lors de la seule interrogation. 2) d'Où vient le "sistema" objet venu? Pourquoi le 'app' argument n'est utilisé dans la méthode?
- c'est que l'ensemble de la méthode? la chasse d'eau et s'engager n'ont pas de sens là. De quelle façon les données de l'ancien? Quel est le problème avec elle? Qu'avez-vous fait à l'intérieur de la portée de l'EntityManager? Quels sont tous les appels et les modifications apportées entre l'ouverture et la fermeture de l'EM? On devine que vous avez laissé l'état de la mémoire de votre entités de tomber de la synchronisation avec la base de données.
Vous devez vous connecter pour publier un commentaire.
Il ya quelques suggestions posté déjà comme le cache partagé est éteint, et pour gérer les références arrière de sorte que le cache est cohérent. Ce sont pour des situations spécifiques qui pourraient être présentes, mais vous n'avez pas fourni assez de dire ce qui se passe vraiment.
Un autre qui est spécifique, mais semble possible en fonction de votre getEntityManager() de l'usage, est si vous réutilisez l'EntityManager instance sans l'effacer. L'EntityManager est titulaire d'une des références à toutes les entités gérées depuis l'EM est nécessaire de retourner la même instance sur requête et de trouver des appels au maintien de l'identité.
Si ce n'est pas déjà fait, va vouloir effacer l'EntityManager ou en obtenir un nouveau en certains points pour libérer de la mémoire et des entités gérées.
clear()
ourefresh()
après le DML d'exécution, vous pouvez trouver plus d'informations dans le lien.Tout d'abord, ne pas utiliser,
venez de définir,
Deuxième, où est votre EntityManager en venir? Ne vous en créer un nouveau à chaque demande/transaction? Si vous n'avez pas tout lu dans l'EntityManager sera dans son (L1) cache. Vous devez appeler clear() ou en créer un nouveau.
Utilisation
ou
Par opposition à la mise en cache de la réponse (que je vais devoir essayer de), vous êtes probablement en cours d'exécution dans une situation où votre entité référencée n'est pas mis à jour.
Lors de l'enregistrement de l'Enfant, vous devez mettre à jour votre référence de Parent, de sorte que le Modèle de Mémoire (cache) correspond à la base de données. C'est assez frustrant, mais la façon dont je le fais avec, c'est à cascade uniquement de la mère.
Ce sera cascade si vous le configurez--ce que j'ai vu, c'est que l'inverse de la cascade (l'enfant de fusion provoque une cascade à la société mère) n'a pas été fiables, issus de mon manque de connaissance dans le sujet.
En bref, si vous gérer la fusion de données de la couche explicitement, le problème disparaît. Je suis réticent à désactiver la mise en cache, car cela pourrait avoir un impact important dans les applications de grande taille, donc, je suis allé dans cette voie. Bonne chance, et s'il vous plaît laissez-nous savoir votre approche.
1) Affiner le code
2)Retirez @Cache (type=CacheType.AUCUN) de votre classe d'entité
3) Pas besoin de changer persistence.xml
L'utilisation de l'EntityManager est la clé. J'ai atteint la solution parfaite après des mois: