首页 > 解决方案 > 由带有 LazyNoProxy 注释的 JoinColumns 映射的实体的提取不适用于标准查询 - 导致 n + 查询

问题描述

我们有一个实体 Film,它具有各种映射实体 Producer、MainActor 都延迟加载,以及一个实体 BiggestStar 延迟加载并通过 @JoinColumns 注释在 2 个不同的列 FirstName 和 LastName 上加入,没有外键。

public class Film implements PersistentAttributeInterceptable {
   private PersistentAttributeInterceptor interceptor;

   @OneToOne(fetch = FetchType.LAZY, mappedBy = "film")
   @LazyToOne(LazyToOneOption.NO_PROXY)
   @LazyGroup("producer")
   public Producer getProducer() {
       return producer;
   }

   @ManyToOne(fetch = FetchType.LAZY)
   @NotFound(action = NotFoundAction.IGNORE)
   @JoinColumns(foreignKey = @javax.persistence.ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT),
    value = {@JoinColumn(name = "starFirstName", referencedColumnName = "firstName", insertable = false, updatable = false),
        @JoinColumn(name = "starLastName", referencedColumnName = "lastName", insertable = false, updatable = false)})
   @LazyToOne(LazyToOneOption.NO_PROXY)
   @LazyGroup("biggestStar")
   public BiggestStar biggestStar() {
       if (interceptor != null) {
           return (F) interceptor.readObject(this, "biggestStar", biggestStar);
       }
       return biggestStar;
   } 
}

我有一个条件查询,我想在其中获取实体 Film 并获取 Producer、BiggestStar 但不是 MainActor。

CriteriaQuery<Film> query = cb.createQuery(Film.class);
Root<Film> root= query.from(Film.class);
root.fetch(Film_.producer, JoinType.LEFT);
root.fetch(Film_.biggestStar, JoinType.LEFT);
query.select(root).where(...)

现在,如果我执行此查询,我会准确记录一个 SQL 语句,该语句准确地获取我的所有对象,并且我得到表 Film、Producer 和 BiggestStar 的所有值,但是当film.getBiggestStar()调用 getter 时,会发出另一条语句选择连接列在电影桌上。检查电影对象时,最大星为空,直到您执行 getBiggestStar() 但随后不向最大星表发出另一个命令,而仅向电影表发出命令。

喜欢

select starFirstName, starLastName from Film

导致 n+1 查询,因为我使用此查询来获取表的数据。

我不知道我在这里做错了什么,如何通过保持延迟加载在一个查询中快速获取所有这些实体。

一些免责声明:

标签: hibernatehibernate-mappingcriteriacriteria-api

解决方案


推荐阅读