Java Spring数据-实体未更新
我有一个实体Java Spring数据-实体未更新,java,hibernate,jpa,spring-data,dirty-checking,Java,Hibernate,Jpa,Spring Data,Dirty Checking,我有一个实体Customer和Spring数据接口CustomerRepository,如下所示: public interface CustomerRepository extends JpaRepository<Customer,Long> { Customer findCustomerByName(String name); } 我不明白为什么它会打印:Customer(id=1,name=John,姓氏=Smith) 据我所知,Hibernate使用脏检查机制来更新
Customer
和Spring数据接口CustomerRepository
,如下所示:
public interface CustomerRepository extends JpaRepository<Customer,Long> {
Customer findCustomerByName(String name);
}
我不明白为什么它会打印:Customer(id=1,name=John,姓氏=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重新加载它,但它会立即分离
- 修改分离的实体-不保存
- 您在另一个事务中重新加载条目,但看不到更新
@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);
}
}