In Hibernate, both session.persist() and session.save() are used to save an entity object to the database. Although their final effects are similar, there are key differences in their usage and design intent:
-
Return Values:
- The
session.save()method returns the identifier (ID) of the object, typically a generated primary key. - The
session.persist()method does not return any value (i.e., void). This aligns with EJB3 specifications and is designed to transition the object's state to persistent.
- The
-
Impact of Method Invocation Timing on Persistence State:
- The
session.save()method can be called at any time, regardless of the current Session state. - The
session.persist()method must be invoked within a transaction boundary to ensure the entity's state transitions from transient to persistent. If called outside a transaction, the INSERT statement may not execute immediately until the transaction begins.
- The
-
Handling Cascade Types:
- The
session.save()method does not consider cascade attributes (CascadeType). If entity A has a relationship with entity B, and entity B is newly created, callingsave()on entity A alone will not persist entity B. - The
session.persist()method handles cascade settings (e.g.,@Cascade) based on entity configuration; if cascade types include PERSIST, it will automatically persist entity B when callingpersist()on entity A.
- The
Practical Examples
Suppose there are two entity classes, Customer and Order, where Customer has multiple Orders. In business logic, we create a new Customer and a new Order, and set this Order to belong to the new Customer.
If using session.save():
javaCustomer customer = new Customer("张三"); Order order = new Order("订单001"); customer.addOrder(order); session.save(customer); // Note: Here, order is not saved; an additional call to session.save(order) is required to save the order.
If using session.persist() with cascade operations set in the Customer entity:
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); // Here, no additional call to persist(order) is needed because cascade settings handle it automatically.
When choosing between session.save() and session.persist(), select the method that best fits specific requirements and design. Typically, persist() is preferable when adhering to JPA specifications and handling cascade persistence.