Search code examples
javahibernatetransactionscriteriahibernate-session

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)?


Solution

  • 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.