2013-05-29 120 views
1

我看了類似的問題,但答案沒有工作對我來說+ 1選擇執行..JPA @OneToOne關係n

問題:當我選擇在具有加入提取到一些查詢多個父實體其子實體@OneToOne,查詢爲其每個子實體執行select語句。沒有join fetch它按預期執行。


Suser實體有關係;與它的主人

@OneToOne(optional = false, fetch = FetchType.LAZY) 
@Cascade(value = { CascadeType.PERSIST, CascadeType.DELETE }) 
public SuserStats stats; 

@OneToOne(fetch=FetchType.LAZY) 
@Cascade(value = {CascadeType.PERSIST}) 
public Profile profile; 

SuserStats實體關係;與它的主人

@OneToOne 
@JoinColumn 
public Suser owner; 

Profile實體關係;

@OneToOne(optional = false, mappedBy = "profile") 
public Suser user; 

當我執行的查詢;

select u from Suser u where u.id in 
    (select f.targetUser.id from Friendship f where f.sourceUser = ?) 

如預期的那樣,僅在單個查詢中獲取關係的id。沒關係。 lazy fetch正在工作..

但是,當我改變它; (這次我想讓他們取出)

select u from Suser u left join fetch u.stats s left join fetch u.profile where u.id in 
    (select f.targetUser.id from Friendship f where f.sourceUser = ?) 

2n + 1查詢正在執行..每個查詢配置文件和統計關係。我在這裏解釋了很多方法,但他們沒有解決我的問題。我想我失去了一些東西基本在定義父 - 子關係..

在此先感謝..

回答

2

我找到了解決辦法;

注意:CascadeType修改與問題和解決方案無關。

注2:我申請相同的策略來Profile實體,因此沒有必要再次寫

SuserStats實體;

@MapsId 
@OneToOne 
@JoinColumn(name="id") 
public Suser owner; 

Suser entity;

@OneToOne(mappedBy="owner",optional=false,fetch=FetchType.LAZY,cascade=javax.persistence.CascadeType.PERSIST,javax.persistence.CascadeType.REMOVE}) 
@PrimaryKeyJoinColumn 
public SuserStats stats; 

這些變化,Stats的主列成爲Suserid(如外鍵)。所以 默認的懶惰關係和聯合提取按需提供工作。