Bonjour à tous !
j'utilise Hibernate depuis quelques mois et je suis maintenant confronté sur un problème de fraicheur de données. En effet j'ai l'impression qu'hibernate maintient un cache des données récupérées depuis la base de données, ce qui est embêtant car je suis obligé de restart tomcat afin qu'hibernate prenne compte des changements.
J'utilise donc hibernate, tomcat 6 et deux bases de données, une oracle et une sybase. Pour l'instant on s'intéresse à la base de données Oracle.
Le process est le suivant, je récupère une liste d'objets populés depuis la base de données, là l'utilisateur depuis l'application appel un web service qui s'occupe via Hibernate de mettre à jour des données ou en insérer. Puis lors du refresh de l'application (appel web service qui fait un session.createQuery(...).list() et retourne les valeurs), les données mises à jour ne le sont pas, et les données insérées ne sont pas présentes. Pourtant elles le sont bien dans Oracle (update et insert).
Je cherche donc depuis hier à desactiver ce comportement, je suis tombé sur un tas de posts parlant de mettre 3 options en plus dans le fichier de config d'hibernate, je l'ai fait mais ça n'a rien changé. J'ai tenté de changer le cache mode sur l'objet session, ça ne change rien non plus.
Je vais vous mettre un peu de code histoire que vous voyez de quoi il en retourne:
Code:
class HibernateAction {
public static void withSession(final SessionAction sa) throws Exception {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtil.currentSession();
tx = session.beginTransaction();
sa.execute(session);
tx.commit();
} catch (HibernateException e) {
if (tx != null && tx.isActive()) {
try {
tx.rollback();
} catch (HibernateException e1) {
System.err.println("Error rolling back transaction");
}
throw e;
}
}
}
}
Je m'en sers comme ceci :
Code:
HibernateAction.withSession(new SessionAction() {
public void execute(Session session) {
List<MyObject> list = session.createQuery("select m from MyObject m where ...").list();
}
}
La session d'Hibernate est stoquée dans une classe nomée HibernateUtil qui utilise ThreadLocal.
Code:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
private static final ThreadLocal<Session> session = new ThreadLocal<Session>();
static {
try {
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
} catch (HibernateException ex) {
// log...
throw ex;
}
}
public static Session currentSession() {
Session s = session.get();
if (s == null) {
try {
s = kplusSessionFactory.openSession();
s.setCacheMode(CacheMode.REFRESH);
session.set(s);
} catch (HibernateException e) {
// log...
throw e;
}
}
return s;
}
public static void closeSession() {
Session s = session.get();
session.set(null);
if (s != null && s.isOpen()) {
s.close();
}
}
}
J'ai donc lu aussi sur internet d'utiliser session.clear() ou même session.evict(Object) mais dans les deux cas ça me jette une exception lorsque j'utilise des relations style one-to-many, du à la lazy initialisation.
Pouvez-vous m'indiquer où est le problème et comment je peux résoudre ça ?
Merci d'avance à ceux qui pourront m'aider :)