JPA——关于对象状态
JPA(hibernate)映射对象的4种状态:
临时状态/瞬时状态:刚new出来的对象,没有持久化(persist)即没有被entityManager关联。无id对象
Person person = new Person(); // 瞬时状态 person.setName("张三");
持久化状态/托管状态:已经与entityManager关联,变动会同步到数据库中(数据库中有或者即将有的对象)
EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(person); // 变为托管状态 person.setAge(30); // 自动同步到数据库
游离状态:已经被持久化,但是不被entityManager关联,变更不会同步到数据库中(数据库中有对应记录)
em.detach(person); // 显式分离 // 或 em.close(); // 关闭EntityManager会使所有托管对象变为分离状态
删除状态:被标记为删除,但还没在数据库中删除的对象(事务提交后会被删除)
临时状态->持久化->持久状态 持久状态->事务关闭/分离->游离状态 游离状态->find/merge->持久状态 持久状态->remove->删除状态
关于状态的问题:
游离状态不能直接变为删除状态:游离状态已经脱离了entityManager的管理,无法被remove()删除。因此想删除一个数据,需要先find出来,让他变成持久化状态
学了上述四种状态,我们知道在springboot开发使用jpa框架时,使用@transactional注解是很有必要的:
1.JPA的自动脏数据检查、延迟加载只能在事务内生效。自动脏数据检查即:使用事务后修改不需要显示调用save也能自动同步
例如:
@Transactional public void batchUpdate() { List<Product> products = productRepository.findAll(); products.forEach(p -> p.setPrice(p.getPrice() * 1.1)); // 只会在事务提交时生成一条批量UPDATE语句 }
@Transactional public void updateProduct(Long id, String newName) { Product product = productRepository.findById(id).orElseThrow(); product.setName(newName); // 自动被脏检查捕获 // 无需显式调用 repository.save(product) }
2.事务结束后对象会变为游离状态,不能被删除。

浙公网安备 33010602011771号