我试着模仿这个公认的答案https://stackoverflow.com/a/39746931/3214777 仅更新某些对象的字段时使用hibernate代理。我的代码看起来像:
@Transactional
public void updateStudentYear(int uniqueNumber, int newYear) {
Student studentProxy = studentRepository.getOne(uniqueNumber);
studentProxy.setYear(newYear);
studentRepository.save(studentProxy);
}
问题是hibernate执行完全选择和完全更新。日志如下:
2021-03-10 20:24:23.240调试118757---[main]org.hibernate.sql:选择student0\u0.unique\u number作为unique\u n1\u 1\u 0,student0\u0.name作为name2\u 1\u 0,student0\u0.team作为team3\u 1\u 0,student0\u0.year作为year4\u 1\u 0来自student0的student0\u where student0\u0.unique\u number=?
2021-03-10 20:24:23.268调试118757---[main]org.hibernate.sql:更新students set name=?,team=?,year=?其中唯一的\u编号=?
我原以为只会发出一个“update year”语句,但令我惊讶的是,似乎所有操作都像经典的findone()/save()对操作一样完成。我错了吗?
1条答案
按热度按时间9w11ddsr1#
不,很遗憾,相关问题的答案是错误的。这个
getOne()/getReference()
方法并不是更新单个字段,而是在必要时避免撞击数据库。这种方法的实用性在于
在这种情况下
Foo
将从数据库中获取,但是Bar
不会的。jpa总是更新update语句中的所有字段,尽管我不确定它是否会受到实现本身的脏检查的影响。hibernate有@dynamicupdate来限制列,但是jpa没有为它指定一般的机制。