Java Hibernate getNamedQuery执行其他更新表
我有这样的代码。我知道这是一个遗留代码,可能不是最好的Java Hibernate getNamedQuery执行其他更新表,java,sql,hibernate,named-query,Java,Sql,Hibernate,Named Query,我有这样的代码。我知道这是一个遗留代码,可能不是最好的 final Student student = loadStudentById(13); student.setLastAccessedTime(new Date()); student.setNote(20); updateWithHQLUsingNamedQueries(student);//HERE WE UPDATE BOTH FIELDS USING NAMEDQUERIES private void updateWithHQ
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
后来我看到NamedQuery的更新
update student set c01=:c01 and lastAccessedTime=:time and note=:note where id=:id
我的问题是
为什么Hibernate在定期更新中提交学生字段?我是说,就像我在执行更新之前做的一样?这个学生在任何地方都没有被录取
session.update(student);
我知道他们只更新脏字段,因为我使用的是DynamicRue,可能上次更新(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没有持久化,也会更新到DB中。它实际上不会将更改提交给
学生
,如果您在事务中,它只会将更改刷新到数据库中。在Query
对象上调用executeUpdate
时,它会在执行查询之前刷新所有挂起的更改,以确保数据一致性
您的
loadStudentById
显然返回一个托管实体,由Hibernate跟踪。它保留原始状态的副本,并在每次刷新时将其与对象的当前状态进行比较。如果您不想跟踪其中的更改,可以调用session.detach(student)
(如果使用Hibernate 5.2,其中它与EntityManager接口合并)。它会更新一次,因为您更改了托管对象,就像我说的,第二次是您正在运行的手动查询。Flush将所有更改发送到没有@列(updateable=false)
或子实体对应级联选项的DB字段。如果需要,可以在实体上设置新属性,然后调用session.flush()
在数据库中更新它们。