Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate始终运行冗余查询_Java_Mysql_Hibernate_One To One - Fatal编程技术网

Java Hibernate始终运行冗余查询

Java Hibernate始终运行冗余查询,java,mysql,hibernate,one-to-one,Java,Mysql,Hibernate,One To One,我的数据模型中有一个OneToOne关系,hibernate总是查询这两个实体以生成结果集 这是数据模型 @Entity public class C1 { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = t

我的数据模型中有一个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

但是

每次我查询C1 hibernate时,每行生成一个连接两个实体数据的查询,并在第一个的结果中为每行生成N个查询(甚至在我访问结果集之前)

范例

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
重复查询的结果会出现在第一个大查询的行中。。。有没有办法避免这些不必要的请求?我试着把它设为懒惰,但没用

我运行的代码很简单

HibernateUtils.createNewSession().createCriteria(C1.class).list();
我甚至没有在结果触发嵌套查询之前访问它


我正在使用hibernate 5.10 e mysql 5.7.17

我得到了一个解决方案,但我不完全明白为什么

映射OneToOne与JPA hibernate的关系时,hibernate会将外键放在具有“targetEntity”属性的实体上(具有属性NO的实体是在ATRIBUTE值中设置的实体)

当通过结构中包含外键的实体进行查询时,hibernate将自动查询嵌套实体(我不知道原因)

为了解决之前的相关问题,我只需要将注释更改为

@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;

我找到了一个解决办法,但我不完全明白为什么

映射OneToOne与JPA hibernate的关系时,hibernate会将外键放在具有“targetEntity”属性的实体上(具有属性NO的实体是在ATRIBUTE值中设置的实体)

当通过结构中包含外键的实体进行查询时,hibernate将自动查询嵌套实体(我不知道原因)

为了解决之前的相关问题,我只需要将注释更改为

@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;

记住这两件事

OneToOne的默认抓取策略是“急切”

如果关联不可为空,则LAZY只能在OneToOne关联上工作

您的问题类似于N+1选择问题

解决N+1选择问题:

HQL获取连接

或者

从 C1 C1 左连接提取 c1.c2

二等舱

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

记住这两件事

OneToOne的默认抓取策略是“急切”

如果关联不可为空,则LAZY只能在OneToOne关联上工作

您的问题类似于N+1选择问题

解决N+1选择问题:

HQL获取连接

或者

从 C1 C1 左连接提取 c1.c2

二等舱

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

可选=假?请尝试使用trueoptional=false?请用真的试一试