2017-03-01 60 views
0

通過hibernate使用postgresql數據庫。 我有一個實體(表)TeamInfo(bb_team_info),並試圖執行以下代碼:Hibernate逐個加載不需要實體標記爲lazy fetch type

strQuery.append("SELECT * from bb_team_info WHERE id in (SELECT bb_team_info_id FROM bb_team_league_info tl WHERE tl.bb_league_id = :leagueID)"); 
    Query query2 = em.createNativeQuery(strQuery.toString(), TeamInfo.class); 
    query2.setParameter("leagueID", leagueID.getId()); 
    List<TeamInfo> myteaminfolist = query2.getResultList(); 

這裏是TeamInfo類:

是由
@Entity 
@Table(name="bb_team_info") 
@BatchSize(size=50) 
public class TeamInfo implements Serializable { 
private Integer id; 
... some fields here ... 
private TeamFinance finance; 
private Manager manager; 

public TeamInfo() { 
} 

.... 

@OneToOne (mappedBy="teamInfo", fetch=FetchType.LAZY) 
public Manager getManager() { 
    return manager; 
} 
... 


@OneToOne(targetEntity=TeamFinance.class, fetch=FetchType.LAZY, mappedBy="teamInfo", cascade=CascadeType.ALL) 
public TeamFinance getFinance() { 
    return finance; 
} 

} 

實際要求(從PostgreSQL的日誌中看到):

SELECT * from bb_team_info WHERE id in (SELECT bb_team_info_id FROM bb_team_league_info tl WHERE tl.bb_league_id = $1) 

而這恰恰是預期的,但後來我看到許多疑問是這樣的:

select ... from bb_team_finances teamfinanc0_ where teamfinanc0_.bb_team_info_id=$1... 
select ... from bb_manager where manager0_.bb_team_info_id=$1... 
select ... from bb_team_finances teamfinanc0_ where teamfinanc0_.bb_team_info_id=$1... 
select ... from bb_manager where manager0_.bb_team_info_id=$1... 

爲什麼休眠選擇這些表,如果提取類型設置爲懶惰?爲什麼它不會至少在兩個查詢中完成(首先選擇所有經理然後選擇財務)?

回答

1

如果實體不「擁有」它們,Hibernate必須熱切地獲取實體的OneToOne關係。這是因爲它需要知道是否使用null作爲關係或代理/實體。

爲了在兩個查詢中進行加載,您需要一個不同的獲取策略。使用@Fetch(FetchMode.SUBSELECT)。這裏有一些很好的例子:https://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/

+0

有沒有什麼辦法可以告訴hibernate它應該使用代理,因爲關係在數據庫中始終存在? – maximus

+0

如果我做雙向關係怎麼辦? – maximus

+0

嘗試在@ OneToOne上設置'optional = false' –

相關問題