I'm facing problems with Hibernate that seems to be related to the cache object.
I have an entity, let's call it A, with a list attribute mapped with @OneToMany (cascade = CascadeType.ALL, mappedBy = "atributo")
. The objects in the list are class B entities and have a bidirectional relationship with A. Then B has an attribute mapped with @ManyToOne (cascade = CascadeType.MERGE)
. I get object A from the database and add a new object B in list A using the call and Session.update(A)
.
The problem arises when all objects of type A are ready, using the call session.createCriteria(A.class).list();
, access exactly to an object A that I updated and object B NOT is present in the list. When opening PostgreSQL, both objects are updated and correctly saved, but sometimes in the query in Criteria the data is not the same (some times it is correct and some is not).
I tried to use session.refresh (A) after update A, but the problem still persists.
About Caffé's comment, I believe that's what is happening, but I still can not find a solution to the problem. Below is the implementation of the GenericDAO save and update methods:
** Note that our GenericDAO class is implanted using ThreadLocal .
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
public GenericDao(final Class<T> objectClass) {
this.objectClass = objectClass;
}
public Class<T> getObjectClass() {
return this.objectClass;
}
public T save(final T object) throws HibernateException {
try {
final Session s = this.getSessionHibernate();
s.beginTransaction();
s.save(object);
s.getTransaction().commit();
s.flush();
return object;
} catch (final HibernateException ex) {
GenericDao.logger.error(ex);
Session s = this.getSessionHibernate();
s.getTransaction().rollback();
s.clear();
throw new HibernateException(ex);
}
}
public void update(final T object) throws HibernateException {
try {
final Session s = this.getSessionHibernate();
s.update(object);
} catch (final HibernateException ex) {
GenericDao.logger.error(ex);
Session s = this.getSessionHibernate();
s.getTransaction().rollback();
s.clear();
throw new HibernateException(ex);
}
}
/**
* Get session opened of the Hibernate
*
* @return {@link Session}
*/
public Session getSessionHibernate() {
Session s = (Session) GenericDao.threadSession.get();
// Open a new Session, if this thread has none yet
if (s == null) {
s = this.getHibernateTemplate().getSessionFactory().openSession();
GenericDao.threadSession.set(s);
}
return s;
}