gpt4 book ai didi

java - Spring数据-实体未更新

转载 作者:太空宇宙 更新时间:2023-11-04 10:39:43 25 4
gpt4 key购买 nike

我有一个实体Customer和Spring数据接口(interface)CustomerRepository,如下所示:

public interface CustomerRepository extends JpaRepository<Customer,Long> {
Customer findCustomerByName(String name);
}

我将 Customer 对象保存在数据库中,然后更新一个字段,如下所示:

customerRepository.save(new Customer("John", "Smith"));
Customer john = customerRepository.findCustomerByName("John");
john.setSurname("Barton");
customerRepository.flush();
customerRepository.findAll().forEach(System.out::println);

我不明白为什么它打印:Customer(id=1, name=John, surname=Smith)。

据我所知,Hibernate 使用脏检查机制来更新持久状态下的实体。因此,更改后的姓氏应该在事务结束期间传播到数据库(但事实并非如此 - 即使我将此代码分成两个 @Transactional 方法)。难道我做错了什么?我真的需要在每次更改后手动保存对象吗?为什么数据库中的姓氏字段没有更新?

最佳答案

@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerRepoTest {
@Autowired
private CustomerRepository customerRepository;

@Test
//NOTE: No @Transactional
public void testSaveFails() throws Exception {
customerRepository.save(new Customer("John", "Smith"));
Customer john = customerRepository.findCustomerByName("John");
john.setSurname("Barton");
customerRepository.flush();
customerRepository.findAll().forEach(System.out::println);
}

@Test
@Transactional
public void testSaveWorks() throws Exception {
customerRepository.save(new Customer("John", "Smith"));
Customer john = customerRepository.findCustomerByName("John");
john.setSurname("Barton");
//customerRepository.flush(); Flush is not necessary
customerRepository.findAll().forEach(System.out::println);
}

}

解释一下:Hibernate 保留在事务期间加载的对象的缓存。当执行find方法时,会将新加载的对象的id与此缓存中的对象的id进行比较,如果找到,则使用缓存的版本。

  • 这就是带有 @Transactional 的版本有效的原因。
  • 此外,它还解释了为什么不需要刷新 - 它只是强制在事务结束之前写入值。

如果您错过了@Transactional(假设在基础事务上自动提交,这很可能是这种情况):

  • 您在一次事务中保存实体
  • 使用 findCustomerByName 重新加载它,但它会立即分离
  • 您修改分离的实体 - 不保存
  • 您在另一笔交易中重新加载条目,但看不到更新

关于java - Spring数据-实体未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49126229/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com