JPA:按不同列选择任何行

时间:2016-10-20 17:13:28

标签: java hibernate jpa

我有一个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 Hibernate 3.4

3 个答案:

答案 0 :(得分:1)

The solution to this problem was rather simple. First, we have to add the criteria for the multi select columns we seek, and set distinct to 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);

Then, we have to create an additional constructor for the MyEntity class so that it can be created from the results:

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

答案 1 :(得分:0)

这样的事情无法发挥作用?

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

答案 2 :(得分:0)

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

代码

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