4、JPA四大狀态
JPA的四種狀态
- 臨時狀态:剛建立出來,沒有與entityManager發生關系,沒有被持久化,不處于entityManager中的對象。
- 持久狀态:與entityManager發生關系,已經被持久化,您可以把持久化狀态當做實實在在的資料庫記錄。
- 删除狀态:執行remove方法,事務送出之前。
- 遊離狀态:遊離狀态就是送出到資料庫後,事務commit後實體的狀态,應為事務已經送出了,此時實體的屬性任你如何改變,也不會同步到資料庫,因為遊離是沒人管的孩子,不在持久化上下文中。
使用代碼進行示範,幫助了解:
/**
* 遊離狀态
*/
@Test
public void testStatus() {
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer(); // 臨時狀态(瞬時狀态)
customer.setId(5l); // 遊離狀态
customer = entityManager.find(Customer.class,6L); // 持久狀态
entityManager.remove(customer); // 删除狀态(銷毀狀态)
transaction.commit();
}
複制代碼
如圖所示:
- public void persist(Object entity)
- persist方法可以将執行個體轉換為managed(托管)狀态。在調用flush()方法或者送出事務之後,執行個體将會被插入到資料庫中!
對不同狀态下的執行個體A,persist會産生以下操作:
- 如果A是一個new狀态的實體,它會轉為managed狀态
- 如果A是一個managed狀态的實體,它的狀态不會發生任何改變。但是系統仍會在資料庫執行INSERT操作!
- 如果A是一個removed(删除)狀态的實體,他将會轉換為受控狀态!(就是不會再去執行了!)
- 如果A是一個detached(分離)狀态的實體,該方法會抛出IllegalArgumentException異常,具體異常根據不同的 JPA 實作有關!
- public void merge(Object entity)
- merge方法的主要作用是将使用者對一個detached狀态實體的修改進行歸檔,歸檔後産生一個新的managed狀态對象。
對不同狀态下的執行個體A,merge會産生一下操作:
- 如果A是個detached狀态的實體, 該方法會将A的修改送出到資料庫,并傳回一個新的managed狀态的執行個體A2:
- 如果A是個new狀态的實體, 該方法會産生個根據A廣 生的managed狀态實體A2;
- 如果A是個managed狀态的實體, 它的狀态不會發生任何改變。但是系統仍會在資料庫執行UPDATE操作:
- 如果A是個removed狀态的實體, 該方法會 抛出IllegalArgumentException異常。
- public void refresh(Object entity)
- refresh方法可以保證目前的執行個體與資料庫中的執行個體的内容緻。
對 不同狀态下的執行個體A. refresh會産生以下操作:
- 如果A是- 個new狀态的執行個體,不會發生任何操作, 但有可能會抛出異常,具體情況根據不同JPA實作有關!
- 如果A是一個managed狀态的執行個體,它的屬性将會和資料庫中的資料同步。
- 如果A是個removed狀态的執行個體, 該方法将會抛出異常Entity not managed
- 如果A是一個detached狀态的實體,該方法會抛出異常。
- public void remove(Object entity)
- remove方法可以将實體轉換為removed狀态,并且在調用flush()方法或送出事物後删除資料庫中的資料。
對不同狀态下的執行個體A. remove會産生以下操作:
- 如果A是一個new狀态的執行個體,A的狀态不會發生任何改變,但系統仍會在資料庫中執行DELETE語句;
- 如果A是個managed狀态的執行個體, 它的狀态 會轉換為removed;
- 如果A是個removed狀 态的執行個體,不會發生任何操作:
- 如果A是個detached狀态的實體, 該方法将會抛出異常。
緩存測試
/**
* 緩存測試
*/
@Test
public void testCache() {
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 這裡的緩存是一級緩存,隻查詢了一次!
Customer customer = entityManager.find(Customer.class,3L);
Customer customer2 = entityManager.find(Customer.class,3L);
transaction.commit();
}