Java Hibernate始终运行冗余查询
我的数据模型中有一个OneToOne关系,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
@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?请用真的试一试