【问题标题】:JPA: Select any row by distinct columnJPA:按不同的列选择任何行
【发布时间】:2016-10-20 17:13:28
【问题描述】:

我有一个 SQL 表,其中包含一些数据:

------------------+------------------------+------------------------
      Name        +        Zone            +      School
-------------------------------------------+------------------------
      Joe         +  Coolzone              +   VCU
      Mike        +  ReallyCoolZone        +   ODU
      Kyle        +  NotcoolZone           +   ODU

我在这里尝试做的是使用 JPA 只选择一行,带有区域和学校,其中学校是不同的。

因此,我期待结果:

CoolZone, VCU
ReallyCoolZone, ODU

我曾尝试在 JPA 中发出这样的查询,但我收到一条错误消息,指出返回了多个结果:

select distinct a.zone, a.school from MyEntity a

根据我所阅读的内容,此错误是有道理的,原因有两个。 a) 当我们发出 select 语句时,我们不会返回整个实体,而是部分 b) jpa 不知道如何将这些值映射到我的实体。

根据我的阅读,我可以通过创建一个新的构造函数并明确说明应该如何构造返回的对象来解决这个问题。这篇文章在这里提到了这一点:https://stackoverflow.com/a/24710759/5655414

在我创建一个新的构造函数后,我的查询字符串相当于这样:

select new MyEntity(distinct a.zone, a.school) from MyEntity a

我收到一条错误消息:

 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: distinct

这个应该放在什么位置? 如果这段代码很疯狂而且毫无意义,是否有更有效的方法来实现我的目标?

JPA 2.0 休眠 3.4

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    这个问题的解决方案相当简单。首先,我们必须为我们寻找的多选列添加条件,并将 distinct 设置为 true:

    final CriteriaBuilder builder = em.getCriteriaBuilder();
    final CriteriaQuery<MyEntity> criteriaQuery = builder.createQuery(MyEntity.class);
    final Root<MyEntity> myEntity= criteriaQuery.from(MyEntity.class);
    final CriteriaQuery<MyEntity> select = criteriaQuery.multiselect(
                    myEntity.get("zone"), versionTrack.get("school"));
    select.distinct(true);
    

    然后,我们必须为 MyEntity 类创建一个额外的构造函数,以便可以从结果中创建它:

    public MyEntity(final String zone, final String school) {...}
    

    【讨论】:

      【解决方案2】:

      这样的东西不行吗?

      select min(a.zone), a.school from MyEntity a group by a.school
      

      【讨论】:

        【解决方案3】:

        我也面临同样的问题。但是阅读了许多网站,有了解决问题的想法,现在工作正常。 JPA 构造函数不允许'distinct',所以我尝试在构造函数之外。有人找到更好的解决方案,您可以发表评论。

        代码

         @Query("select distinct new com.apptium.eportalcdcdaas.model.CDCField(dl.fieldname,dl.fieldDataType,dl.fieldDesc,"
                    +“dl.fieldPath,dl.parentdomainid,dl.primaryKey) 来自 Delta dl,其中 dl.accountName = ?1 和 dl.applicationName = ?2”
                    + " 和 dl.domainid = ?3 和 dl.subDomainid = ?4")
            List getFieldWithDomainAndSubDomain(String accountname, String applicationname, String domainId,
                    String subDomainId);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-11
          • 1970-01-01
          • 1970-01-01
          • 2015-02-26
          • 1970-01-01
          • 2014-03-11
          • 1970-01-01
          相关资源
          最近更新 更多