select nextval ('hibernate_sequence') // This is for vehicle Id generated : 36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)
使用 persist(entity)重复同样的操作,使用 new Id (比如37,honda)会得到同样的结果;
示例2: 处理分离对象
// Session 1
// Get the previously saved Vehicle Entity
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached object
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.save(entity);
session2.getTransaction().commit();
session2.close();
结果: 您可能期待的车辆 ID: 36获得上一届更新的名称为“丰田”。但是会发生的情况是,一个新的实体保存在 DB 中,新 ID 生成为“ Toyota”,名称为“ Toyota”
// (ii) Using Persist() to persist a detached
// Session 1
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
结果:
Exception being thrown : detached entity passed to persist
因此,最好使用 Perist ()而不是 Save () ,因为在处理瞬态对象时必须谨慎使用保存。
重要提示: 在上面的示例中,vehicle 实体的 pk 是一个生成的值,因此当使用 save ()来持久化一个分离的实体时,hibernate 生成一个新的 id 来持久化。但是,如果这个 pk 不是一个生成的值,那么它将导致异常声明键违反。
Save () : 它立即返回实体的标识符。因为标识符在调用 save 之前已经分配给实体,所以插入不会立即触发。它在会话刷新时触发。
与保存相同。它还在刷新时触发插入。
假设我们有一个实体,它使用生成的标识符如下:
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
@Id
@Column(name = "USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name = "USER_NAME")
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
保存() :
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserName("Gaurav");
session.save(user); // Query is fired immediately as this statement is executed.
session.getTransaction().commit();
session.close();
() :
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserName("Gaurav");
session.persist(user); // Query is not guaranteed to be fired immediately. It may get fired here.
session.getTransaction().commit(); // If it not executed in last statement then It is fired here.
session.close();
现在假设我们有如下定义的相同实体,没有 ID 字段生成注释,也就是说 ID 将手动分配。
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
@Id
@Column(name = "USER_ID")
private int userId;
@Column(name = "USER_NAME")
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
保存() :
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.save(user); // Query is not fired here since id for object being referred by user is already available. No query need to be fired to find it. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();
持续() :
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.persist(user); // Query is not fired here.Object is made persistent. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();
当从事务内部调用保存或持久化时,上述情况是正确的。
保存和持久化之间的其他不同点是:
可以在事务外部调用 save ()。如果使用指定的标识符,那么因为 id 已经可用,所以不会立即触发任何插入查询。只有在刷新会话时才触发查询。
如果使用了生成的标识符,那么由于需要生成 id,因此会立即激发 insert。但它只能保存主实体。如果实体有一些级联实体,那么这些实体将不会保存在 db 中。当刷新会话时,它们将被保存。