无法获取由带有LazyNoProxy批注的JoinColumns映射的实体,不适用于criteriasquery-导致n +查询

时间:2019-01-07 17:30:09

标签: hibernate hibernate-mapping criteria hibernate-criteria criteria-api

我们有一个实体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;
   } 
}

我有一个条件查询,我想在其中获取电影实体并获取制作人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时,会发出另一条语句来选择film表上的连接列。 在检查影片对象时,在执行getBiggestStar()之前,largestStar为空,但随后不会对bigestStar表发出另一个命令,而仅对影片表发出命令。

喜欢

select starFirstName, starLastName from Film

当我使用该查询来获取表的数据时,会导致n + 1个查询。

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

一些免责声明:

  • 我知道我可以使用本机SQL
  • 我没有控制数据库的权限,因此无法添加外键或改进数据架构
  • 数据库是Oracle 12

0 个答案:

没有答案