2017-07-26 64 views
0

所以我使用spring數據,並且遇到了一個問題,試圖爲此hibernate查詢返回一個列表。Spring Data創建內部聯接OneToMany

interface NewFooWithMetadataDAO : Repository<Foo, Int> { 
    @Query("""SELECT NEW com.foo.persistence.sql.po.NewFooWithMetadataPO(
        b.id, 
        b.accountId, 
        bi.profitCenterSegmentation, 
        b.fooContext 
       ) 
       from 
        Foo b 
        left join b.fooIntent bi 
        left join b.fooContext bc 
       where 
        account_id = ?1 
       group by 
        b.id 
    """) 
    fun findByAccountId(accountId: Int): List<NewFooWithMetadataPO> 
} 

這個查詢創建一個這樣的hibernate查詢。

select 
    foo0_.id as col_0_0_, 
    foo0_.account_id as col_1_0_, 
    foo_buc1_.profit_center_segmentation as col_2_0_, 
    . as col_3_0_ 
from 
    foo foo0_ 
    left outer join foo_intent foo_buc1_ on foo0_.foo_intent_id=foo_buc1_.id 
    left outer join foo_context_map foocont2_ on foo0_.id=foocont2_.foo_id 
    inner join foo_context_map foocont3_ on foo0_.id=foocont3_.foo_id 
where 
    account_id=? 
group by foo0_.id 

這是一個錯誤的查詢。

我也嘗試過bc而不是b.fooContext在HQL中,但後來我沒有收到一個集合,我得到一個FooContextPO。

我的實體都喜歡

@Entity 
@Table(name = "foo") 
data class Foo(
     @Id 
     val id: Int, 
     @Column(name= "account_id") 
     val accountId: Int, 

     @OneToOne 
     @JoinColumn(name = "foo_intent_id", referencedColumnName = "id") 
     @NotFound(action=NotFoundAction.IGNORE) 
     val fooIntent: FooIntentPO, 


     @OneToMany 
     @JoinColumn(name = "foo_id", referencedColumnName = "id") 
     @NotFound(action=NotFoundAction.IGNORE) 
     val fooContext: Collection<FooContextPO> 
){ 
     @Entity 
     @Table(name = "foo_intent") 
     data class FooIntentPO(
       @Id 
       val id: Int, 
       @Column(name = "profit_center_segmentation") 
       val profitCenterSegmentation: String 
     ) 
     @Entity 
     @Table(name = "foo_context_map") 
     data class FooContextPO(
       @Id 
       val id: Int, 
       @Column(name = "foo_id") 
       val fooId: Int, 
       @OneToOne 
       @JoinColumn(name = "context_id", referencedColumnName = "id") 
       val context: ContextPO 
     ) 
     @Entity 
     @Table(name = "context") 
     data class ContextPO (
       @Id 
       val id: Int, 
       @ManyToOne 
       @JoinColumn(name = "foo_id", referencedColumnName = "id") 
       val foo: Foo, 
       @Column(name = "context") 
       val context: String 
     ) 

} 

data class NewFooWithMetadataPO(
     val id: Int, 
     val accountId: Int?, 
     val profitCenterSegmentation: String?, 
     val context: Collection<Foo.FooContextPO> 
) 

是否有某種方式,我得到了LEFT JOIN正確這裏沒有它產生內部聯接工作?

回答

0

你肯定得到內部聯接由於選擇下面

SELECT NEW com.foo.persistence.sql.po.NewFooWithMetadataPO(
        b.id, 
        b.accountId, 
        bi.profitCenterSegmentation, 
        b.fooContext 
       )... 

你獨立外側連接到FooContextPO作爲bc所以對應的屬性b.fooContext如果你想避免內部聯接,你無法引用映射的屬性fooContext。所以你需要選擇bc

由於實際的底層數據,您是否僅獲得1條記錄?當您選擇bc而不是b.fooContext時,生成的SQL是否也不正確?如果是這樣的話......你能分享一下那個sql的樣子嗎?