乐闻世界logo
搜索文章和话题

Hibernate 中 session . Persist 和 session . Save 有什么区别?

2 个月前提问
2 个月前修改
浏览次数21

1个答案

1

在Hibernate中,session.persist()session.save() 都用于将一个实体对象保存到数据库中。虽然它们的最终效果相似,但在使用方法和设计意图上有一些关键的区别:

  1. 返回值

    • session.save() 方法会返回该对象的标识符(ID),这个ID通常是一个生成的主键。
    • session.persist() 方法则不会返回任何值(即void)。这符合了EJB3规范的要求,设计上更倾向于使得对象的状态转换为持久态。
  2. 方法调用时机对持久化状态的影响

    • session.save() 方法可以在任何时候被调用,无论当前Session的状态如何。
    • session.persist() 方法则必须在事务边界内调用,确保实体的状态由瞬时状态转变为持久化状态。如果在没有事务的情况下使用persist方法,可能不会立即执行INSERT语句,直到事务开始。
  3. 级联类型的处理

    • session.save() 方法不会考虑级联属性(CascadeType)。如果实体A具有与实体B的关系,且实体B也是新创建的,那么仅调用实体A的save方法,并不会保存实体B。
    • session.persist() 方法则会根据实体中的级联设置(如 @Cascade),在调用实体A的persist方法时,也会对实体B进行持久化操作,如果级联类型包括PERSIST的话。

实际应用举例

假设有两个实体类,Customer和Order,其中Customer有多个Order。在业务逻辑中,我们创建了一个新的Customer和一个新的Order,并设置这个Order属于新的Customer。

如果使用 session.save()

java
Customer customer = new Customer("张三"); Order order = new Order("订单001"); customer.addOrder(order); session.save(customer); // 注意,这里没有保存order,需要额外调用session.save(order)来保存订单

如果使用 session.persist() 并且在Customer实体中设置了级联操作:

java
@Entity public class Customer { @OneToMany(mappedBy = "customer", cascade = CascadeType.PERSIST) private Set<Order> orders = new HashSet<>(); public void addOrder(Order order) { orders.add(order); order.setCustomer(this); } } Customer customer = new Customer("张三"); Order order = new Order("订单001"); customer.addOrder(order); session.persist(customer); // 这里不需要额外调用persist(order),因为已经通过级联设置自动处理

在选择使用 session.save()session.persist() 时,需要根据具体需求和设计选择更符合场景的方法。通常,persist方法在遵循JPA规范和处理级联持久化时是更好的选择。

2024年7月22日 21:06 回复

你的答案