JpaRepository getOne() 获取并更新整个对象

Avr*_*Pop 5 java proxy spring hibernate spring-data-jpa

我试图模仿这个已接受的答案 /sf/answers/2782285201/在仅更新某些对象的字段时使用 Hibernate 代理。我的代码如下所示:

  @Transactional
public void updateStudentYear(int uniqueNumber, int newYear) {
    Student studentProxy = studentRepository.getOne(uniqueNumber);
    studentProxy.setYear(newYear);
    studentRepository.save(studentProxy);
}
Run Code Online (Sandbox Code Playgroud)

问题在于 Hibernate 既执行完全选择又执行完全更新。这是日志:

2021-03-10 20:24:23.240 DEBUG 118757 --- [ main] org.hibernate.SQL :从学生中选择student0_.unique_number作为unique_n1_1_0_,student0_.name作为name2_1_0_,student0_.team作为team3_1_0_,student0_.year作为year4_1_0_ Student0_ 其中student0_.unique_number=?

2021-03-10 20:24:23.268 DEBUG 118757 --- [ main] org.hibernate.SQL : 更新学生集 name=?, team=?,year=? 其中 unique_number=?

我原以为只会发出一个“更新年份”语句,但令我惊讶的是,看起来一切都是像经典的 findOne()/save() 对操作一样完成的。我错了吗?

Kay*_*man 4

不,不幸的是,链接问题的答案是错误的。该getOne()/getReference()方法并不是要更新各个字段,而是要避免在需要时访问数据库。

该方法的用处在于以下情况

Foo foo = fooRepo.findOne(id);
Bar barProxy = barRepo.getOne(id);
foo.setBar(barProxy);
fooRepo.save(foo);
Run Code Online (Sandbox Code Playgroud)

在这种情况下Foo将从数据库中获取,但Bar不会。

JPA 将始终更新更新语句中的所有字段,尽管我不确定它是否会受到实现自身的脏检查的影响。Hibernate 有@DynamicUpdate来限制列,但 JPA 没有为其指定通用机制。