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.事务结束后对象会变为游离状态,不能被删除。

 

posted @ 2025-07-20 22:53  天启A  阅读(21)  评论(0)    收藏  举报