【问题标题】:Spring data - entity not updatedSpring数据 - 实体未更新
【发布时间】:2018-08-14 00:56:16
【问题描述】:

我有一个实体Customer和Spring数据接口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 使用dirty checking 机制来更新处于持久状态的实体。因此,更改的姓氏应该在事务结束期间传播到数据库(但它不会 - 即使我将此代码分成两个 @Transactional 方法)。难道我做错了什么?每次更改后我真的需要手动 save 对象吗?为什么数据库中的姓氏字段没有更新?

【问题讨论】:

  • 因为你从不使用 barton 保存,或者创建 2 个对象
  • 请注意@Transactional 仅适用于公共方法。

标签: java hibernate jpa spring-data dirty-checking


【解决方案1】:
@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 重新加载它,但它会立即分离
  • 您修改了分离的实体 - 不保存
  • 您在另一个事务中重新加载条目,但看不到您的更新

【讨论】:

    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多