---
# System prepended metadata

title: hibernate 2/20 觀念
tags: [hibernate]

---

# hibernate 2/20 觀念
###### tags: `hibernate`

#### @ 永續類別
![](https://i.imgur.com/GHBAmni.png)

#### 可寫可不寫(不寫要自行修改)
![](https://i.imgur.com/HdKIuwZ.png)

#### 第五章介紹
![](https://i.imgur.com/zmtknAm.png)

#### 永續類別
![](https://i.imgur.com/DMLL1qV.png)
![](https://i.imgur.com/ofLLUSZ.png)

### 32 編寫Hibernate程式的通則
![](https://i.imgur.com/JFDwq54.png)
建工廠
![](https://i.imgur.com/ZvmrEPp.png)
對 [HibernateUtils] F3 OR ctrl+左鍵
可進入以下畫面
![](https://i.imgur.com/7mnzmPK.png)
類別載入過不會再載入
實作類別介面做工廠
![](https://i.imgur.com/iKVpttp.png)
呼叫工廠(兩種方法都合法)
![](https://i.imgur.com/S8wVHeG.png)
開啟交易
![](https://i.imgur.com/jYnB7bl.png)
這個類別只做開啟交易
![](https://i.imgur.com/K6PZxuA.png)
再度丟出例外
![](https://i.imgur.com/k84Le3f.png)
多個表格異動
![](https://i.imgur.com/ofb7oSF.png)
其中一個DAO出問題可能是企業邏輯異常(企業組絕定的邏輯)

還原異動前的狀態
![](https://i.imgur.com/84nPKC8.png)
* **Hibernaet**
    * 交易邊界 哪裡開始哪裡結束(交易)
    * 結束要回滾(還原到正常狀態)
    * 即便做查詢也要開啟交易Hibernate的規定

多個DAO都用同一個執行緒 Session物件 DAO會拿到一樣的的Session物件
關閉 Session
openSession(自行關閉) getCurrentSession
![](https://i.imgur.com/pZPrJ5Z.png)
有了 	@Transactional 註解那邊通通不用寫 (需要Spring)
![](https://i.imgur.com/mLLxyGU.png)
### 47~51 程式實作
![](https://i.imgur.com/XKhmy4X.png)
* **Hibernate分為**
    *  一對多 多對一 看主角是誰?
    * 主角不同會有差異
![](https://i.imgur.com/vLOFEBV.png)
Spring都使用介面 (不要寫類別名稱) 實作介面類別 
![](https://i.imgur.com/ZhJvDJ5.png)
修改
![](https://i.imgur.com/vZ991FS.png)
使用組態檔
![](https://i.imgur.com/XLhDgUn.png)
Impl結尾都是實作介面類別的名字
建立工廠需要組態資訊
* **sql**
    * 外鍵 建在多方建一個就可
    * 主鍵 建在一方

連動 
![](https://i.imgur.com/RmUiZd3.png)
all的時候
![](https://i.imgur.com/d3Xy57N.png)

![](https://i.imgur.com/mjQFlEL.png)

當儲存 關聯物件沒有儲存 要順便存起來
如果有其他的永續物件沒有儲存會出現這個
![](https://i.imgur.com/juot4t5.png)

### 54 永續儲存的類別(永續類別)Persistence Class
![](https://i.imgur.com/T05metH.png)
final類別不可以有子類別

需要告訴組態檔
![](https://i.imgur.com/7btni4n.png)
![](https://i.imgur.com/udpDAO8.png)

### 55 POJO類別
![](https://i.imgur.com/uZlVgMU.png)
不要實作任何界面或者繼承父類別
Domain類似業務相關
OID可挑流水號做

### 56 POJO類別範例
越單純越好
![](https://i.imgur.com/dVCYwfT.png)

### 58 永續物件的生命週期(重要)
1. Transien  短暫 暫時
2. Persistent 永久保留 永續
3. Detached 分離物件 沒有跟儲存環境連接的
4. Removed 刪除移除
![](https://i.imgur.com/gwsKN3I.png)

### 59 物件在Hibernate內生命週期的變化
![](https://i.imgur.com/JTMDnTg.png)

### 60 Transient(臨時)狀態
![](https://i.imgur.com/dz8HxVu.png)

### 口試常問 61 Persistent(永續)狀態
![](https://i.imgur.com/MIlVTYt.png)
如果一個永續物件的屬性改變 它有可能會更新也可能不更新

### 口試 62 Detached(分離)狀態
![](https://i.imgur.com/xsYCB1a.png)
evict移出一次 clear全部逐出
* **Persistent(永續)狀態**
    *  永續物件 有oid 有主見紀錄 放session緩存
* **Detached(分離)狀態**
    *  分離物件 分離也有主見對應值 不會緩存 不受到hibernate監控

###  63 Removed(移除)狀態
移除就是刪除對應的紀錄
![](https://i.imgur.com/RbIoLKe.png)

### 64 JUnit 單元測試工具
![](https://i.imgur.com/6d7Xzn4.png)

#### 實作
![](https://i.imgur.com/J4eixUd.png)
![](https://i.imgur.com/Ah513eC.png)
![](https://i.imgur.com/YqwQdej.png)
![](https://i.imgur.com/tqtpikZ.png)


```click=
package jut2;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MyJUint02 {

	@Before
	public void setUp() throws Exception {
		System.out.println("Before");
	}

	@After
	public void tearDown() throws Exception {
		System.out.println("After");
	}

	@Test
	public void test() {
		System.out.println("Test");
	}
	
	@Test
	public void test1() {
		System.out.println("Test1");
	}
}

```
![](https://i.imgur.com/veneY5i.png)
### 找專案
![](https://i.imgur.com/VG7oMqN.png)
詳細尋找
找目前專案
![](https://i.imgur.com/uUtit8P.png)

### 註解顏色
![](https://i.imgur.com/Kw0OHxA.png)

### debug
![](https://i.imgur.com/XcmQg5v.jpg)
![](https://i.imgur.com/sFyJpV1.png)
![](https://i.imgur.com/lxCBEFF.png)
直接跳到下一個中斷點
![](https://i.imgur.com/UszrXIC.png)

### 72-73 Session介面的get()與load()方法
![](https://i.imgur.com/MLc3vY1.png)
Lazy Loading延遲載入
* **Member.class**
    * 儲存Member類別的內容的物件
    * 一個class型別的物件
    * ![](https://i.imgur.com/LsgSDGv.png)
![](https://i.imgur.com/9sIviPK.png)
一對多 多對一 的多方會用到Lazy Loading

### 74  Session介面的get()
![](https://i.imgur.com/QpN1cTi.png)

### 實作畫面
![](https://i.imgur.com/VIKuh8F.png)
所有的中斷點
![](https://i.imgur.com/yvyprQ3.png)
![](https://i.imgur.com/KdXsBTJ.png)
```click=
org.hibernate.LazyInitializationException: could not initialize proxy [ch03._00.model.BookBean#3] - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:170)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:310)
	at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
	at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
	at ch03._00.model.BookBean$HibernateProxy$5tKaOrzS.getAuthor(Unknown Source)
	at ch03._00.MethodsOfSession.loadDemo01(MethodsOfSession.java:153)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
```
![](https://i.imgur.com/9uUnu9E.png)

![](https://i.imgur.com/tLDnyqa.png)
![](https://i.imgur.com/w2hrKrI.png)

mydebug
![](https://i.imgur.com/NMooDoP.png)
![](https://i.imgur.com/BWPVLg7.png)

## merge
merge傳回值是永續物件 但參數不是

### 實作dao
```click=
	@SuppressWarnings("unchecked")
	@Override
	public List<MemberBean> getAllMembers() {
		String hql = "FROM MemberBean";//FROM 類別名稱
		Session session = factory.getCurrentSession();
		List<MemberBean> list = session.createQuery(hql).getResultList();
		return list;
	}
    
    	@Override
	public MemberBean getMember(int pk) {
		Session session = factory.getCurrentSession();
		MemberBean mb = session.get(MemberBean.class, pk);
		return mb;
	}
    
    @Override
	public int deleteMember(int pk) {
		int count = 0;
		Session session = factory.getCurrentSession();
		MemberBean mb = new MemberBean();
		mb.setPk(pk);
		session.delete(mb);
		count++;
		return count;
	}

	@Override
	public int updateMember(MemberBean mb) {
		int count = 0;
		Session session = factory.getCurrentSession();
		session.merge(mb);
		count++;
		return count;
	}
```
### Service
```click=
@Override
	public List<MemberBean> getAllMembers() {
		List<MemberBean> list = null;
		Session session = factory.getCurrentSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			list = dao.getAllMembers();
			tx.commit();
		} catch (Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			throw new RuntimeException();
		}

		return list;
	}
    
    @Override
	public MemberBean getMember(int pk) {
		
			MemberBean mb = null;	
			Session session = factory.getCurrentSession();
			Transaction tx = null;
			try {
				tx = session.beginTransaction();
				mb = dao.getMember(pk);
				tx.commit();
			} catch (Exception e) {
				if(tx != null) {
					tx.rollback();
				}
				e.printStackTrace();
				throw new RuntimeException();
			}

		return mb;
	}
    
    @Override
	public int deleteMember(int ipk) {
		int n = 0;
		
		Session session = factory.getCurrentSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			n = dao.deleteMember(ipk);
			tx.commit();
		} catch (Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new RuntimeException();
		}

		return n;
	}
    
    	@Override
	public int updateMember(MemberBean mb) {
		int n = 0;
		Session session = factory.getCurrentSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			n = dao.updateMember(mb);
			tx.commit();
		} catch (Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new RuntimeException();
		}
		return n;
	}
```

### 102 延遲加載Lazy Initialization
![](https://i.imgur.com/VY9T4NU.png)

### 103 在MVC架構下http請求地處理流程
![](https://i.imgur.com/wDrZOQK.jpg)

### 104-107 解決Lazy Loading的做法
![](https://i.imgur.com/0pSCBg2.png)
EAGER急切

![](https://i.imgur.com/KNBD0NF.png)

![](https://i.imgur.com/ilQygW1.png)
交易都沒有commit
session都是開啟狀態
控制器做完才回到Filter才去關閉commit

![](https://i.imgur.com/urZ7dGr.png)
![](https://i.imgur.com/zOhDEDg.png)

![Uploading file..._ov2sqz688]()

> [name=黑咖啡好喝]