Spring hibernate把我的查询搞砸了

Spring hibernate把我的查询搞砸了,spring,hibernate,repository,hsqldb,Spring,Hibernate,Repository,Hsqldb,您好,我编写了以下CriteriaAPI查询,它创建了一个中断的sql select语句,这是由于multiselect。如果我取消对multiselect的注释,查询将按预期工作,但问题是我不想拥有所有数据。在我的门户对象中有几个关系,在我目前的情况下,完全不需要加载它们 方法如下所示: @Override public Optional<Portal> loadPortalData(long clientId) { log.trace("loading dat

您好,我编写了以下CriteriaAPI查询,它创建了一个中断的sql select语句,这是由于multiselect。如果我取消对multiselect的注释,查询将按预期工作,但问题是我不想拥有所有数据。在我的门户对象中有几个关系,在我目前的情况下,完全不需要加载它们

方法如下所示:

  @Override
  public Optional<Portal> loadPortalData(long clientId)
  {
    log.trace("loading data for client with id '{}'", clientId);
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Portal> criteriaQuery = criteriaBuilder.createQuery(Portal.class);
    Root<Portal> root = criteriaQuery.from(Portal.class);
    criteriaQuery.multiselect(root.get(Portal_.codes),
                              root.get(Portal_.certificate))
                 .where(criteriaBuilder.equal(root.get(Portal_.id), clientId));
    try
    {
      return Optional.of(entityManager.createQuery(criteriaQuery).getSingleResult());
    }
    catch (NoResultException noResult)
    {
      return Optional.empty();
    }
  }
30 Mai 2017 07:12:56,305 [main] TRACE mypackage.repository.PortalDaoImpl (PortalDaoImpl.java:39) - loading data for client with id '1'
Hibernate: 
select
    . as col_0_0_,
    portal0_.certificate as col_1_0_ 
from
    portal portal0_ 
inner join
    Code authorisat1_ 
        on portal0_.id=authorisat1_.client_id 
inner join
    certificate certificat2_ 
        on portal0_.certificate=certificat2_.id 
where
    portal0_.id=1
如果我使用multiselect,有什么建议说明为什么hibernate会像这样把我的查询搞得一团糟

编辑:

@Entity
@Table(name = "portal")
public class Portal
{
   ...
   @Valid
   @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER, mappedBy = "client")
   private Set<Code> codes = new HashSet<>();

   @Valid
   @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "certificate", referencedColumnName = "id")
   private Certificate certificate;
   ...
}

不能选择整个集合(
code

假设您希望结果的每一行由代码和证书组成,那么JPQL查询应该是

select code, portal.certificate from Portal portal 
left join portal.codes as code
where portal.id = :id
当然,这将返回给定门户中代码的行数,而不仅仅是一行

避免加载门户实体的其他列可能是过早的、不必要的优化。这样做应该容易得多

em.find(Portal.class, id)
或者,如果您想在同一查询中加载代码和证书

select distinct portal from Portal portal 
left join fetch portal.certificate
left join fetch portal.codes
where portal.id = :id
它将返回一个包含门户的唯一行,以及预取的代码集


如果您真的希望应用程序速度更快,那么您应该在默认情况下使关联变慢(尤其是对许多关联),并在需要时使用fetch连接。

门户实体的代码是什么?为什么不使用JPQL进行这种静态查询?为什么门户条目的代码很重要?JPQL也会产生同样的错误嘿,你才是需要帮助的人。投票结束,因为您不想提供要求的信息,允许我免费帮助您。
select distinct portal from Portal portal 
left join fetch portal.certificate
left join fetch portal.codes
where portal.id = :id