我看了类似的问题,但答案对我没有用..
问题:当我在一个查询中选择多个父实体,这些实体已连接到某些@OneToOne
子实体时,查询会为每个子实体执行select
语句。没有join fetch
,它就会按预期执行。
Suser
实体有关系;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@Cascade(value = { CascadeType.PERSIST, CascadeType.DELETE })
public SuserStats stats;
@OneToOne(fetch=FetchType.LAZY)
@Cascade(value = {CascadeType.PERSIST})
public Profile profile;
SuserStats
与其所有者的实体关系;
@OneToOne
@JoinColumn
public Suser owner;
Profile
与其所有者的实体关系;
@OneToOne(optional = false, mappedBy = "profile")
public Suser user;
当我执行查询时;
select u from Suser u where u.id in
(select f.targetUser.id from Friendship f where f.sourceUser = ?)
正如所料,只在单个查询中获取关系的id。没关系。 lazy fetch
正在运作..
然而,当我把它改为; (这次我希望他们获取)
select u from Suser u left join fetch u.stats s left join fetch u.profile where u.id in
(select f.targetUser.id from Friendship f where f.sourceUser = ?)
正在执行2n + 1个查询..每个查询和统计信息关系。我在这里尝试了许多方法,但他们并没有解决我的问题。我想在定义亲子关系时我错过了一些基本的东西..
提前感谢..
答案 0 :(得分:2)
我找到了解决方案;
注意: CascadeType
修改与问题和解决方案无关。
注2:我将相同的策略应用于Profile
实体,因此无需再次编写
SuserStats
实体;
@MapsId
@OneToOne
@JoinColumn(name="id")
public Suser owner;
Suser
实体;
@OneToOne(mappedBy="owner",optional=false,fetch=FetchType.LAZY,cascade=javax.persistence.CascadeType.PERSIST,javax.persistence.CascadeType.REMOVE})
@PrimaryKeyJoinColumn
public SuserStats stats;
通过这些更改,Stats
的主要列成为id
的{{1}}(作为外键)。所以
默认的懒惰关系和按需加入提取工作正常。