Hibernate Criteria setReadOnly 不适用于第二个查询
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";
}
如上面的代码,criteria
的 setReadOnly
为真,因此 firstName
不会是 AAA
(在数据库中),但它已重置setReadOnly
对 criteria2
为假,为什么 firstname
没有变成 BBB
(在数据库中)?
好的,经过一段时间的研究,我设法找到了原因。
当第一个查询加载对象时,hibernate 将对象置于持久上下文中并将对象标记为 read-only
。这意味着该对象最终不会被刷新。
在第二次调用加载对象时,hibernate 在持久上下文中获取对象,而不是再次调用数据库,因为获取是基于主键的。由于它是从持久上下文加载的,因此它仍将处于 read-only
状态。
为了让对象重新变回flush-able,我们可以用setReadOnly(Object entity, boolean readOnly)
设置对象的readOnly
。
@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";
}
如上面的代码,criteria
的 setReadOnly
为真,因此 firstName
不会是 AAA
(在数据库中),但它已重置setReadOnly
对 criteria2
为假,为什么 firstname
没有变成 BBB
(在数据库中)?
好的,经过一段时间的研究,我设法找到了原因。
当第一个查询加载对象时,hibernate 将对象置于持久上下文中并将对象标记为 read-only
。这意味着该对象最终不会被刷新。
在第二次调用加载对象时,hibernate 在持久上下文中获取对象,而不是再次调用数据库,因为获取是基于主键的。由于它是从持久上下文加载的,因此它仍将处于 read-only
状态。
为了让对象重新变回flush-able,我们可以用setReadOnly(Object entity, boolean readOnly)
设置对象的readOnly
。