【问题标题】:JPA @OneToOne relation n+1 select executedJPA @OneToOne 关系 n+1 选择执行
【发布时间】:2013-05-29 17:42:49
【问题描述】:

我看了类似的问题,但答案对我不起作用..

问题:当我在查询中选择多个父实体时,该查询已连接到其某些 @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 个查询。每个查询都用于配置文件和统计信息的关系。我尝试了很多这里解释的方法,但它们并没有解决我的问题。我想我在定义父子关系时遗漏了一些基本的东西..

提前谢谢..

【问题讨论】:

    标签: hibernate jpa playframework


    【解决方案1】:

    我找到了解决办法;

    注意:CascadeType修改与问题和解决方案无关。

    注意2:我对@9​​87654322@实体应用了相同的策略,所以不需要再写了

    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 的主列变为Suser 的id(作为外键)。所以 默认惰性关系和按需加入获取正在工作。

    【讨论】:

      猜你喜欢
      • 2011-04-02
      • 1970-01-01
      • 2018-05-25
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 2019-08-12
      • 1970-01-01
      相关资源
      最近更新 更多