可能的對象狀態選項
您可能已經註意到,當對象附加到 Hibernate 時,其狀態稱為Persistent或Managed。怎麼對?堅持還是管理?
這是可能的,如此,如此。根據 JPA 規範,對象具有 Persist 狀態,而根據 Hibernate 規範,其狀態稱為 Managed。
在 Hibernate 中,使用數據庫是通過org.hibernate.Session類型的對象執行的。根據 JPA,該類應稱為 javax.persistence.EntityManager。這並不是什麼大問題,因為這兩種類型都是接口。
org.hibernate.Session接口聲明如下:
interface Session extends java.lang.AutoCloseable, javax.persistence.EntityManager, HibernateEntityManager, QueryProducer, java.io.Serializable, SharedSessionContract {
}
因此, Session接口具有EntityManager接口中的所有方法。但它也有自己的,它是從早期版本的 Hibernate 繼承的,當時還沒有 JPA 規範。
整個情況描述如下:
![](https://cdn.codegym.cc/images/article/c4cc3931-5115-471e-aec1-812c863f7c4a/1024.jpeg)
讓我們看一下會話接口具有的所有方法,以及它們工作的細微差別。
persist() 方法的細微差別
將對象保存到數據庫時,需要記住兩件事。
首先,保存對象最終將導致執行其中一個 SQL 命令:INSERT 或 UPDATE。其次,這些動作不會在調用對象的方法後立即發生會議,但僅在關閉交易之後。
讓我們考慮一些簡單的情況,例如,您有一個User類:
@Entity
public class User {
@Id
@GeneratedValue
public Integer id;
@Columnt(name=”user_name”)
public String name;
}
讓我們使用persist()方法將其對象保存到數據庫中。
User user = new User();
user.setName("Kolyan");
session.persist(user);
此方法的目的是將新對象保存到數據庫中。如果還沒有這樣的對象,那麼它將通過調用INSERT SQL 方法添加到數據庫中。
如果對像已經在數據庫中,則什麼也不會發生。但是,第三種情況也是可能的 - 嘗試將狀態為 Detached 的對象保存到數據庫中。在這種情況下,將拋出異常。例子:
User user = new User();
user.setName("Kolyan");
session.persist(user);
session.evict(user); // detach the object from the session
session.persist(user); // a PersistenceException will be thrown here!
save() 方法的細微差別
當前的 Hibernate 的 save() 方法是從其先前版本繼承的。它的核心與persist()方法非常相似,它也使用 INSERT 方法向表中添加一條新記錄。然而,它有幾個有趣的細微差別。
首先,該方法返回一個值——對象的新 ID。如您所知,對像在添加到數據庫之前通常沒有 ID,它已經由數據庫分配。因此,會話對象的save()方法返回分配給已保存對象的 ID。
重要的!根據 Hibernate ID 規範,它可以是任何可序列化的對象,而不僅僅是一個數字。它可以是字符串、數字、枚舉,以及任何可以完全放入數據庫表的一列中的一般內容。
save()方法有一個 Serialized 結果類型,因此它的結果必須轉換為正確的類型:
User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);
此外,對於對象的分離狀態,save()方法具有不同的行為。它認為這樣的對像是新的,並簡單地添加另一個條目:
User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);
session.evict(user); // detach the object from the session
Integer id2 = (Integer) session.save(user);
id 和 id2 變量將不同。兩條記錄將添加到數據庫中的表中,每個save()操作一條。