GMsoF GMsoF - 2 months ago 22
Java Question

Hibernate Criteria setReadOnly doesn't work on second query

@RequestMapping("/testing")
@Transactional
public String testing(HttpServletRequest request, final ModelMap model)
{

Criteria criteria = session.getCurrentSession().createCriteria(Student.class);
criteria.setReadOnly(true);

criteria.add(Restrictions.eq("id", "ID12345"));

List<Student> result = criteria.list();

Student abc = result.get(0);

abc.setFirstname("AAA");

Criteria criteria2 = session.getCurrentSession().createCriteria(Student.class);
criteria2.setReadOnly(false);


criteria2.add(Restrictions.eq("id", "ID12345"));

result = criteria2.list();

Student abc2 = result.get(0);

abc2.setFirstname("BBB");

return "testing";
}


As the code above, it has
setReadOnly
to true for
criteria
, so
firstName
will not be
AAA
(in database), but it has reset the
setReadOnly
to false for
criteria2
, why the
firstname
didn't become
BBB
(in database)?

Answer

Ok, after some time of research, I managed to find out the reason.

While the first query load up the object, hibernate put the object in persistent context and mark the object as read-only. Meaning the object will not be flushed in the end.

During second call to load up the object, hibernate fetch the object in persistent context instead of making call to database again, because the fetch is based on primary key. Since it is loaded from persistent context, it will be still in read-only state.

In order to let the object back to flush-able again, we can use setReadOnly(Object entity, boolean readOnly) to set back the readOnly of the object.