我有一個Parent表,它有一個id欄位作為PK,還有一個Child表,它有自己的id作為PK,還有一個parent_id列,它參考Parent表的id作為FK。
假設我在Parent表中有4個id,我在Child表中有4行,像這樣:
| id| parent_id|
1 1
2 2
3 3
4 3
正如你所看到的,值為'4'的Parent id沒有孩子。
Parent表的映射是一個簡單的pojo,只有一個欄位,Child物體的映射是這樣的:
@Entity
@Table(name = "child")
public class Child {
@Id
@Column
private Integer id;
@ManyToOne
private Parent parent。
// getters & setters
}
從java代碼中,我運行這個查詢:
TypedQuery<Child> practicesQuery = dataBaseContext.getCurrentSession().createQuery("")
"FROM Child c WHERE c.parent.id = :id", Child.class).setParameter("id", id)。
return practicesQuery.getResultList()。
我試著為前3個id運行它,hibernate為每個 "fetch "操作生成了2個select陳述句,就像這樣:
Hibernate:
選擇
child0_.id作為id1_59_。
選擇child0_.parent_id為parent_i3_59_,選擇child0_.parent_id為parent_i3_59_。
從
孩子child0_
其中
child0_.parent_id=?
Hibernate:
選擇
parent0_.id as id1_111_0_
從
parent parent0_
其中
parent0_.id=?
但是當我對id = 4運行同樣的查詢時,只執行了第一個查詢。
為什么hibernate試圖獲取那些有孩子的父類(id為1、2和3),但卻不對沒有孩子的父類(id為4)執行選擇陳述句?當然,在這種情況下,第二個選擇總是無用的。
謝謝你
uj5u.com熱心網友回復:
@ManyToOne關系的默認獲取策略是EAGER。由于你對父級檔案使用了默認的獲取策略,Hibernate在父表上觸發了第二次查詢,以加載父級記錄。
從JPA規范來看,@ManyToOne關系的默認獲取型別是
。public abstract FetchType fetch
(Optional) 該關聯是應該被懶惰地加載還是必須被急切地獲取。EAGER策略是對持久化提供者運行時的一個要求,即必須急切地獲取關聯的物體。LAZY策略是對持久化提供者運行時的一個提示。
默認情況下。
javax.persistence.FetchType.EAGER
如果你不想急切地加載父物件,請將獲取型別設定為lazy
。@Entity
@Table(name = "child")
public class Child {
@Id
@Column
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
private parent parent。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/327140.html
標籤:
