2016-08-30 6 views
0
@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"; 
    } 

Как видно из кода выше, он имеет setReadOnly к истинным для criteria, так firstName не будет AAA (в базе данных), но это сбросить setReadOnly ложь для criteria2 , почему firstname не стал BBB (в базе данных)?Hibernate Критерии SetReadOnly не работает на втором запросе

+0

Вам не нужно сохранять объект? –

+0

@ScaryWombat Я уже упрощаю сценарий, в моем фактическом коде он имеет несколько уровней обслуживания и класса модели и несколько методов между ними. Поэтому я создал этот упрощенный сценарий, чтобы выяснить причину моей проблемы. Да, я хочу сохранить объект, но я бы не смог удалить 'criteria.setReadOnly (true)' (это в другом методе). – GMsoF

+0

Что делать, если вы поместите второй вызов методом, отмеченным @Transactional (распространение = Propagation.REQUIRES_NEW), чтобы начать новую транзакцию? – StanislavL

ответ

0

Хорошо, после некоторого времени исследований мне удалось выяснить причину.

В то время как первый запрос загружает объект, hibernate помещает объект в постоянный контекст и помещает объект как read-only. Значение объекта не будет очищено в конце.

Во время второго вызова для загрузки объекта спящий режим выдает объект в постоянном контексте вместо повторного вызова в базу данных, поскольку выборка основана на первичном ключе. Поскольку он загружается из постоянного контекста, он все равно будет находиться в состоянии read-only.

Чтобы вернуть объект обратно в режим промывки, мы можем использовать setReadOnly(Object entity, boolean readOnly), чтобы вернуть readOnly объекта.