【问题标题】:JPA2 Criteria API runtime cast from varchar(25) to decimalJPA2 Criteria API 运行时从 varchar(25) 转换为十进制
【发布时间】:2014-05-19 00:12:34
【问题描述】:

所以我在类似主题上看到堆栈溢出的所有线程,但我没有找到解决我的问题的方法。

我正在尝试创建一个 Criteria 查询,我得到了这个 SQL(第一个 SQL,简化):

SELECT latitude FROM stations WHERE (ABS(latitude - 45.893227) <= 0.2)

但它给了我这个错误:

java.sql.SQLDataException: The resulting value is outside the range for the data type DECIMAL/NUMERIC(31,31).

那是因为我的纬度是 varchar(25) 类型。所以这修复了它(第二个 SQL):

SELECT latitude FROM stations WHERE (ABS(CAST(latitude AS DECIMAL) - 45.893227) <= 0.2)

但是现在我需要用 Criteria 语法来做。这是我的方法:

public List<Stations> searchStations(Float distance, List<Address> addresses) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Stations> cq = cb.createQuery(Stations.class);
    Root<Stations> stations = cq.from(Stations.class);

    //this <Float> cast actually does nothing:
    Expression<Float> Lat = stations.get("latitude");
    Expression<Float> Lon = stations.get("longitude");

    //make a list of conditions
    List<Predicate> predicates = new ArrayList<>();
    for (Address a : addresses) {
        Float aLat = Float.valueOf(a.getLatitude());
        Float aLon = Float.valueOf(a.getLongitude());


        //condition: |station.Lat - address.Lat| <= distance
        //le() = lessThan, abs() = absolute, diff() = subtraction

        Predicate condLat = cb.le(cb.abs(cb.diff(Lat, aLat)), distance);
        Predicate condLon = cb.le(cb.abs(cb.diff(Lon, aLon)), distance);

        //if I do: Lat.as(Float.class) it won't cast on runtime!

        predicates.add(condLat);
        predicates.add(condLon);
    }

    //add the array of conditions to the WHERE expression, connected with AND:
    cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

    TypedQuery<Stations> q = em.createQuery(cq);
    return q.getResultList();
}

使用该代码,我得到了第一个 SQL,我想要第二个。我只是无法获得运行时转换功能。我尝试过的 Criteria 类型转换函数在运行时不起作用。我该如何解决这个问题?

【问题讨论】:

    标签: java criteria-api


    【解决方案1】:

    经过一番搜索,我找到了一种使用 java derby DOUBLE 函数通过 CriteriaBuilder 函数强制运行时强制转换的方法:

        Expression Lat = stations.get("latitude");
    
        Expression LatCast = cb.function("DOUBLE", Float.class, Lat);
    

    我得到了这个 SQL 查询转换:

    DOUBLE(LATITUDE)
    

    参考:http://www.javadb.net/double-function.htmlhttp://www.objectdb.com/api/java/jpa/criteria/CriteriaBuilder/function_String_Class__Expression__

    它适用于大多数受支持的数据库功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      相关资源
      最近更新 更多