【问题标题】:Spring Data Creates Inner Join On OneToManySpring Data 在 OneToMany 上创建内部联接
【发布时间】:2018-01-02 09:17:38
【问题描述】:

所以我使用的是 spring 数据,但在尝试获取此休眠查询的列表时遇到了问题。

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>
}

这个查询创建一个像这样的休眠查询。

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

这是一个错误的查询。

我也尝试过在 HQL 中使用 bc 而不是 b.fooContext,但是我没有得到一个集合,我得到一个 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>
)

有什么方法可以让左连接在这里正常工作而不产生内部连接?

【问题讨论】:

    标签: mysql spring spring-data hql kotlin


    【解决方案1】:

    由于在下面选择映射属性b.fooContext,您肯定会获得内部连接

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

    您作为bc 单独外部连接到FooContextPO,因此如果您想避免内部连接,则不能引用映射属性fooContext。所以你需要选择bc

    由于实际的基础数据,您只获得了 1 条记录吗?当您选择bc 而不是b.fooContext 时生成的SQL 是否看起来也不正确?如果是这样...你能分享一下那个 sql 的样子吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2014-10-08
      • 2021-03-04
      • 1970-01-01
      • 2014-01-18
      • 2018-08-01
      • 2021-11-15
      相关资源
      最近更新 更多