Hibernate getNamedQuery 执行其他UPDATE TABLE
Hibernate getNamedQuery executes other UPDATE TABLE
我有这样的代码。我知道这是遗留代码可能不是最好的代码。
final Student student = loadStudentById(13);
student.setLastAccessedTime(new Date());
student.setNote(20);
updateWithHQLUsingNamedQueries(student);//HERE WE UPDATE BOTH FIELDS USING NAMEDQUERIES
private void updateWithHQLUsingNamedQueries(final Student student){
final Query query = session.getNamedQuery("namedQuery");
query.setParameter("lastAccessedTime",student.getLastAccessedTime());
query.setParameter("note",student.getNote());
query.setParameter("c01",c01Field);
query.executeUpdate();//HERE HIBERNATE UPDATE THE STUDENT LIKE session.update(student);
}
我们也在使用
@org.hibernate.annotations.DynamicUpdate(value=true)
@org.hibernate.annotations.SelectBeforeUpdate(value=true)
一切正常,但在 SQL 日志记录中,我可以首先看到两个更新,就像这样的常规更新。
休眠更新
update com.models.Student HIBERNATE MESSAGE
update student set lastAccessedTime=:time and note=:note where id=:id
后来我看到了 namedQueries 的更新
update student set c01=:c01 and lastAccessedTime=:time and note=:note where id=:id
我的问题是?
为什么 Hibernate 在定期更新中提交学生字段我的意思是就像我在 executeUpdate 之前做的那样?学生没有任何承诺。
session.update(student);
我知道他们只更新脏字段,因为我使用的是 DynamicTrue,也许最后一次更新 (NamedQuery) 似乎被浪费了。但是为什么 Hibernate 像定期更新一样提交学生对象???导致两次更新?降低性能?
感谢@coladit 的回答,但如果我像这样修改我的代码设置 属性
final Student student = loadStudentById(13);
student.setLastAccessedTime(new Date());
student.setNote(20);
student.setAnotherProperty(value);//THIS CHANGE IS PERSISTED IN DB
flush 是否 属性 在 DB 中持久存在?????因为我修改了 属性 并更新到数据库中,即使 namedQuery 没有保留..
如果您处于事务中,它实际上不会将更改提交给 Student
,它只是将它们刷新到数据库中。当您在 Query
对象上调用 executeUpdate
时,它会在执行您的查询之前刷新所有未决更改,以确保数据一致性。
您的 loadStudentById
显然 returns 一个托管实体,由 Hibernate 跟踪。它保留原始状态的副本,并在每次刷新时将其与对象的当前状态进行比较。如果您不想跟踪其中的更改,可以调用 session.detach(student)
(如果使用与 EntityManager 接口合并的 Hibernate 5.2)。
我有这样的代码。我知道这是遗留代码可能不是最好的代码。
final Student student = loadStudentById(13);
student.setLastAccessedTime(new Date());
student.setNote(20);
updateWithHQLUsingNamedQueries(student);//HERE WE UPDATE BOTH FIELDS USING NAMEDQUERIES
private void updateWithHQLUsingNamedQueries(final Student student){
final Query query = session.getNamedQuery("namedQuery");
query.setParameter("lastAccessedTime",student.getLastAccessedTime());
query.setParameter("note",student.getNote());
query.setParameter("c01",c01Field);
query.executeUpdate();//HERE HIBERNATE UPDATE THE STUDENT LIKE session.update(student);
}
我们也在使用
@org.hibernate.annotations.DynamicUpdate(value=true)
@org.hibernate.annotations.SelectBeforeUpdate(value=true)
一切正常,但在 SQL 日志记录中,我可以首先看到两个更新,就像这样的常规更新。
休眠更新
update com.models.Student HIBERNATE MESSAGE
update student set lastAccessedTime=:time and note=:note where id=:id
后来我看到了 namedQueries 的更新
update student set c01=:c01 and lastAccessedTime=:time and note=:note where id=:id
我的问题是?
为什么 Hibernate 在定期更新中提交学生字段我的意思是就像我在 executeUpdate 之前做的那样?学生没有任何承诺。
session.update(student);
我知道他们只更新脏字段,因为我使用的是 DynamicTrue,也许最后一次更新 (NamedQuery) 似乎被浪费了。但是为什么 Hibernate 像定期更新一样提交学生对象???导致两次更新?降低性能?
感谢@coladit 的回答,但如果我像这样修改我的代码设置 属性
final Student student = loadStudentById(13);
student.setLastAccessedTime(new Date());
student.setNote(20);
student.setAnotherProperty(value);//THIS CHANGE IS PERSISTED IN DB
flush 是否 属性 在 DB 中持久存在?????因为我修改了 属性 并更新到数据库中,即使 namedQuery 没有保留..
如果您处于事务中,它实际上不会将更改提交给 Student
,它只是将它们刷新到数据库中。当您在 Query
对象上调用 executeUpdate
时,它会在执行您的查询之前刷新所有未决更改,以确保数据一致性。
您的 loadStudentById
显然 returns 一个托管实体,由 Hibernate 跟踪。它保留原始状态的副本,并在每次刷新时将其与对象的当前状态进行比较。如果您不想跟踪其中的更改,可以调用 session.detach(student)
(如果使用与 EntityManager 接口合并的 Hibernate 5.2)。