【问题标题】:OneToOne Spring JPA MySQL LAZY load N+1 selectsOneToOne Spring JPA MySQL LAZY 加载 N+1 选择
【发布时间】:2015-10-08 18:29:29
【问题描述】:

在我的 Spring JPA/Data MySQL 应用程序中,我有以下实体:

public class Gene implements Serializable {

    @Id
    @Column(name = "uid")
    private String uid;

    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "gene")
    private GeneStory geneStory;

}

public class GeneStory implements Serializable {

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "gene_uid", referencedColumnName = "uid")
    private Gene gene;

}

我正在尝试通过

加载所有Gene
Query q = em.createQuery("select g from Gene g")
return q.getResultList();

我得到N+1 selects problemGeneStory

现在,在数据库中的每个 Gene 上,我都有针对 GeneStory 的附加查询,如下所示:

select genestory0_.story_id as story_id1_7_0_ ... from gene_stories genestory0_ where genestory0_.gene_uid=?

GeneStory 的延迟加载由于某种原因不起作用。

gene_stories 表的数据库层我也有一个约束——

CONSTRAINT `fk_gene_stories_gene_uid`
    FOREIGN KEY (`gene_uid`)
    REFERENCES `gene` (`uid`)

如何解决这个 N+1 选择问题?我不想将GeneStoryGene 一起加载。我需要在需要时延迟加载它们。

【问题讨论】:

    标签: mysql spring hibernate jpa spring-data


    【解决方案1】:

    根据 JPA 规范:

    延迟获取是对持久性提供程序的提示,可以 通过 Basic、OneToOne、OneToMany、ManyToOne、 ManyToMany 和 ElementCollection 注释及其 XML 等价物

    EAGER 策略是对持久性提供程序的要求 必须急切地获取数据的运行时。 LAZY 策略是一个提示 到持久化提供程序运行时,应该延迟获取数据 首次访问时。 允许急切地实现 获取已指定 LAZY 策略提示的数据

    【讨论】:

    • 换句话说,没有办法在 JPA 中为 OneToOne 实现正常的双向延迟加载?
    • 正如根据规范所说,即使您在注释上指定了 LAZY 提取,它也只是对您的提供者的提示。由提供者来遵循提示或通过急切地获取数据来覆盖它。当我说“提供者”时,我们谈论的是遵循 JPA 规范的任何 ORM 实现(即 Hibernate、EclipseLink 等)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2018-05-25
    • 2017-10-20
    • 1970-01-01
    • 2015-06-24
    • 2016-11-10
    • 1970-01-01
    相关资源
    最近更新 更多