2017-09-26 102 views
0

我在我的數據模型中有OneToOne關係,並且hibernate總是查詢兩個實體以生成結果集。休眠始終運行冗餘查詢

這是數據模型

@Entity 
public class C1 { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, targetEntity = C2.class) 
    private C2 c2; 

    //... other stuff 
} 


@Entity 
public class C2 extends OtherClassOutOfDomain { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "c2") 
    private C1 c1; 

    //... other stuff 
} 

Hibernate來生成我的架構作爲兩個表和C1表有一個外鍵,C2,什麼是完美的我,我會更經常使用的C1。

BUT

每次我查詢C1休眠產生1個查詢加入每行兩個實體數據,並生成在的結果,每行N次查詢第一個(甚至在我訪問的結果SET)

例如

Hibernate (just one): 
    select 
     this_.id as id1_2_1_, 
     this_.c2_id as authDat22_2_1_, 
     this_.bio as bio2_2_1_, 
     this_.blocked as blocked3_2_1_, 
     this_.commentsAmount as comments4_2_1_, 
     this_.confirmed as confirme5_2_1_, 
     this_.deleted as deleted6_2_1_, 
     c22_.id as id1_0_0_, 
     c22_.adid as adid2_0_0_, 
    from 
     c1 this_ 
    inner join 
     c2 c22_ 
      on this_.authData_id=c22_.id 

Hibernate (N times as the size of previous query): 
    select 
     this_.id as id1_2_1_, 
     this_.c2_id as authDat22_2_1_, 
     this_.bio as bio2_2_1_, 
     this_.blocked as blocked3_2_1_, 
     this_.commentsAmount as comments4_2_1_, 
     this_.confirmed as confirme5_2_1_, 
     this_.deleted as deleted6_2_1_, 
     c22_.id as id1_0_0_, 
     c22_.adid as adid2_0_0_, 
    from 
     c1 this_ 
    inner join 
     c2 c22_ 
      on this_.authData_id=c22_.id 
    where 
      this_.authData_id=? 
.....repeat 
.....repeat 
.....repeat 

重複查詢的結果,第一個大的查詢的行中cointained ......有什麼辦法避免這些不必要的請求?我試着設置爲懶惰,但它didn't工作

的代碼我跑得到這個行爲是簡單

HibernateUtils.createNewSession().createCriteria(C1.class).list(); 

我還沒有訪問結果它觸發嵌套查詢之前

我正在使用休眠5.10 e mysql 5.7.17

+0

可選=假?請試試 –

回答

0

我有一個解決方案,但我沒有完全明白爲什麼。

正如JPA映射OneToOne關係冬眠會把外鍵在其上具有「targetEntity」屬性(實體與屬性沒有ENTITY設置好的IN屬性約VALUE)

雖然查詢由實體的實體,其在其結構休眠的外鍵將自動爲嵌套查詢實體(我不知道原因)

爲了解決我以前的相關的問題,我只需要批註改變

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, mappedBy= "c1") 
private C2 c2; 

@OneToOne(fetch = FetchType.LAZY, targetEntity = C1.class) 
private C1 c1; 
0

把這兩件事放在心上。

OneToOne的默認提取策略是EAGER。

如果關聯不可爲空,則LAZY只能在OneToOne關聯中工作。

你的問題類似於N + 1選擇問題

解析N + 1選擇問題:

HQL取加入

要麼

C1 C1 左連接取 c1。C2

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, optional = false, mappedBy= "c1") 
@Fetch(FetchMode.JOIN) 
private C2 c2; 

和在第二類

@OneToOne(fetch = FetchType.LAZY, mappedBy = "c2") 
@Fetch(FetchMode.JOIN) 
private C1 c1;