Hibernate中session.remove()未删实体但session.get()返回null问题
问题描述
操作步骤:
- 调用
session.get(User.class, 11)从数据库获取User实体; - 调用
session.remove(user)将实体标记为待删除(此时Hibernate尚未向数据库发送DELETE请求,实体仍存在于数据库和一级缓存persistenceContext中); - 再次调用
session.get(User.class, 11)却返回null。
疑问:既然该实体仍存在于数据库和一级缓存中,为什么会返回null?
主类代码
public static void main(String[] args) { SessionFactory sessionFactory = HiberUtil.getSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); User user = session.get(User.class, 11); <--- 非null session.remove(user); user = session.get(User.class, 11); <--- null session.getTransaction().commit(); }
User实体类代码
@NoArgsConstructor @AllArgsConstructor @Builder @jakarta.persistence.Entity @Table(name = "Users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Getter private Long id; @Column(unique = true) private String userName; @Embedded private PersonalInfo personalInfo; @Enumerated(EnumType.STRING) private Role role; @Setter @Getter @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "company_id") private Company company; }
解答
这是Hibernate的预期行为,核心原因在于一级缓存(持久化上下文)会追踪实体的状态:
- 调用
session.remove(user)时,Hibernate会把该实体的状态从「持久化」改为「待删除」,但仍将它保留在持久化上下文中; - 再次调用
session.get(User.class, 11)时,Hibernate会先检查一级缓存:- 如果找到状态为「待删除」的实体,不会返回该实体,而是直接返回
null; - 这是Hibernate为了保证持久化上下文的状态一致性——既然实体已经被标记为待删除,就不能再被当作有效实体返回;
- 如果找到状态为「待删除」的实体,不会返回该实体,而是直接返回
- 此时数据库里的记录确实还存在,但Hibernate优先以持久化上下文的状态为准,不会去数据库重新查询(除非调用
session.refresh()或清除缓存)。
简单来说:一级缓存里确实有这个实体,但它的状态是待删除,Hibernate判定它已经「无效」,所以get方法返回null。直到事务提交时,Hibernate才会向数据库发送DELETE请求,真正删除这条记录。
内容的提问来源于stack exchange,提问作者Vsevolod IV
相关产品推荐
相关产品推荐

