客户端代码无法识别@Formula字段 [英] @Formula field is not recognized by client code

查看:118
本文介绍了客户端代码无法识别@Formula字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关:如何多个列上的countDistinct

我有一个包含许多字段的实体类,其中三个字段是longitudelatitudeupdate_time.我正在尝试添加一个将三个连接起来的@Formula字段:

I have an entity class that contains many fields, three of which are longitude, latitude and update_time. I am trying to add a @Formula field that concatenates the three:

@Formula("concat(longitude, latitude, update_time)")
public String fix; 

然后,我想将该字段用作countDistinct查询的一部分:

I would then like to use that field as part of a countDistinct query:

@SuppressWarnings( {"unchecked", "rawtypes"} )
public long getCountDistinctPositions() {
    Session session = sessionFactory.openSession();

    CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();

    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
    Root<Position> position = criteriaQuery.from(Position.class);
    Expression fix = position.get("fix");
    Expression countDistinct = criteriaBuilder.countDistinct(fix);
    criteriaQuery.select(countDistinct);
    Query query = session.createQuery(criteriaQuery);
    Long result = (Long)query.getSingleResult();

    session.close();

    return result;
}

但我不断遇到异常:

java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [fix] on this ManagedType [aaa.Position]

推荐答案

不能查询@Formula字段,它基本上是一个合成字段,只有在执行选择查询时,Hibernate才会填充该字段.

A @Formula field cannot be queried, its basically a synthetic field that Hibernate will populate when a select query is executed only.

对于您的用例,您需要执行:

For your use case, you'd need to execute:

SELECT DISTINCT longitude, latitude, update_time FROM Entity

从JPA查询的角度来看,您需要在所有3个单独的列上执行#countDistinct,而不是在公式列上执行.

From a JPA query perspective, you'd need to execute #countDistinct on all 3 individual columns, not on the formula-column.

想到公式列的最佳方法是,您已经在实体上有效地翻译了以下方法

The best way to think of a formula column is that you've effectively translated the following method on your entity

@Transient
public String getFix() {
  return this.longitude + this.latitude + this.update_time;
}

到数据库在查询时为您串联的属性.

to a property that the database concatenates for you at query-time.

更新

CriteriaQuery<Long> countQuery = cb.createQuery( Long.class );
Root<TheEntity> root = countQuery.from( TheEntity.class );

countQuery.select( cb.count( root.get( "id" ) ) );

Subquery<Integer> subQuery = countQuery.subquery( Integer.class );
Root<TheEntity> subRoot = subQuery.from( TheEntity.class );
subQuery.select( cb.min( subRoot.get( "id" ) ) );
subQuery.groupBy( subRoot.get( "longitude" ), 
   subRoot.get( "latitude" ), 
   subRoot.get( "updateTime" ) );

countQuery.where( root.get( "id" ).in( subQuery ) );

Long count = entityManager.createQuery( countQuery ).getSingleResult();

这篇关于客户端代码无法识别@Formula字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆