С документация гибернации :
Управление данными непосредственно в базе данных (с использованием данных SQL
Язык манипулирования (DML) операторы: INSERT, UPDATE, DELETE)
не влияет на состояние в памяти.
Когда вы используете следующий прямой DML для обновления,
session.createQuery("update Employee set empName = \'Jack_new\' where id=1").executeUpdate();
он обходит контекст персистентности Hibernate (и все кэши). Таким образом, хотя empName
является обновлением до Jack_new
в БД, его экземпляр в контексте постоянства все еще сохраняет старое значение.
Вы можете использовать session.refresh(e1);
для повторного считывания значений для e1
из базовой базы данных, так что e1.empName
будет обновлено до Jack_new
.
Обычно мы не пишем операторы UPDATE вручную для выполнения обновления. Просто установите обновленные значения в свойствах сохраняемых экземпляров. Во время очистки hibernate выполнит грязную проверку, автоматически сгенерирует и выдаст соответствующий SQL-код обновления, чтобы обновить эти грязные экземпляры.
(Ответ на комментарий):
Однако непосредственно перед выполнением tx.commit () я устанавливаю e1.empName в old
значение (то есть значение, возвращаемое e1.getEmpName ()). Все еще последний
в базе данных видно новое значение .?
/**e1 become persisted after save()**/
session.save(e1);
/**e1.empName is updated to new value in the DB , but as the direct DML
will not affect in-memory state , e1.empName in the java side
still keeps the old value***/
session.createQuery("update Employee set empName = \'Jack_new\' where id=1").executeUpdate();
/** As you only set `e1.empName` to its original value , the values of `e1` do
not have any changes. Thus , during the flushing (which occurs at the moment
before `commit()`) , hibernate will consider that `e1` is not dirty and
hence no update SQL will be generated and issued to update e1 .
***/
e1.setEmpName(e1.getEmpName());
Итак, в результате Jack_new
сохраняется в БД.