繁体   English   中英

提取联接导致N + 1个查询或引发org.hibernate.QueryException

[英]Fetch join causes N+1 queries or throws org.hibernate.QueryException

我正在尝试获取一个对象及其关联的查询列表,很不幸,我导致对数据库的N + 1请求,或者被异常“ org.hibernate.QueryException:所查询指定的联接获取,但获取的所有者选择列表中不存在关联”。

请让我为您讲解案件。

以下是我的数据模型:

@Table(name = "first_table")
public class FirstObject {
    @Id
    @Column(nullable = false, name = "first_id")
    private Long id;

    @Column(nullable = false, name = "first_param")
    private String param1;

    @ManyToOne
    @JoinColumn(nullable = false, name = "second_id")
    private SecondObject second;

    ...other columns...
}

@Table(name = "second_table")
public class SecondObject {
    @Id
    @Column(nullable = false, name = "second_id")
    private Long id;

    @Column(nullable = false, name = "second_param")
    private Long param2;

    @ManyToOne
    @JoinColumn(nullable = false, name = "third_id")
    private ThirdObject third;

    ...other columns...
}

@Table(name = "third_table")
public class ThirdObject {
    @Id
    @Column(nullable = false, name = "third_id")
    private Long id;

    ...other columns...
}

数据库关系是正确的,这也正是我在FE中所需要的。 我想要实现的所有方法是使用一个查询获取所有关联,并提供2个条件:

ConditionBuilder condition = new ConditionBuilder()
            .and(FirstObject.second.param2.eq(some_number))
            .and(FirstObject.param1.eq(some_string));

    return from(FirstObject)
            .join(FirstObject.second).fetchJoin()
            .join(FirstObject.second.third).fetchJoin()
            .where(condition.generate())
            .fetch();

不幸的是,这段代码抛出异常:

org.hibernate.QueryException:查询指定的联接获取,但是选择列表中不存在所获取的关联的所有者

我可以使其工作,但可以使用N + 1个查询,但是仅在开发阶段才可接受,因为这会导致性能问题。

...
.join(FirstObject.second).fetchJoin()
.join(FirstObject.second.third)
...

同样在这里:

...
.join(FirstObject.second)
.join(FirstObject.second.third)
...

我试图弄清楚的是如何使休眠来创建一个简单的查询,像这样:

select
    *
from
    first_table table1 
inner join
    second_table table2 
        on table1.second_id=table2.second_id 
inner join
    third_table table3 
        on table2.third_id=table3.third_id 
where
    table1.first_param="some_string"
    table2.second_param=some_number

非常感谢所有帮助,我已经为此奋斗了一段时间,并真的依靠社区。 非常感谢你。

您应该映射实体关系的两端:

例如,在FirstObject您有以下内容:

@ManyToOne
@JoinColumn(nullable = false, name = "second_id")
private SecondObject second;

因此,在SecondObject您应该具有以下功能:

@OneToMany(mappedBy = "second") // this is the name of the field in the class that defines the join relationship
Collection<FirstObject> firstObjects;

ThirdObject您应该具有以下功能:

@OneToMany(mappedBy = "third") // this is the name of the field in the class that defines the join relationship
Collection<SecondObject> secondObjects;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM