【问题标题】:JPA Criteria API - Add days to DATE using ORACLEJPA Criteria API - 使用 ORACLE 将日期添加到 DATE
【发布时间】:2019-01-17 03:22:10
【问题描述】:

我正在尝试使用 JPA Criteria API 过滤特定范围之间的日期。

问题是我的实体中没有直接的日期,我使用日期字段获取日期并将天数(在另一个字段中)添加到该日期。

我环顾四周,看到一些建议在将日期传递给标准生成器之前在 java 中计算日期,但问题是我不知道要添加的天数,因为它取决于表格的特定列。

简化表 OBJECT 有一个日期类型的字段 CREATION_DATE 和一个数字的 EXPIRATION_DAYS。我想按一个可能的过期日期范围进行过滤,我得到 OBJECT 表中每个元素的过期日期,将 EXPIRATION_DAYS 添加到 CREATION_DATE,SQL 查询是:

select * from OBJECT
where CREATION_DATE + EXPIRATION_DAYS 
between to_date('01/01/2018','dd/MM/yyyy') and to_date('01/02/2018','dd/MM/yyyy') 

CriteriaBuilder 我做了一些尝试,但我认为我尝试使用的最佳方法如下:

 CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
 CriteriaQuery<Object> criteria = criteriaBuilder.createQuery(Object.class);
 List<Predicate> predicates...
 predicates.add(criteriaBuilder.between(
        criteriaBuilder.function("AddDate", Date.class, Object.get("creationDate"), criteriaBuilder.literal("day"), Object.get("expirationDays")), 
        dateInit, dateEnd));
 criteria.where(predicates.toArray(new Predicate[]{}));        
 ...
  TypedQuery<Object> query = entityManager.createQuery(criteria);
  return query.getResultList();

我使用function("addDate"...) 方法,问题是我认为 JPA 实现将“addDate”翻译为特定的数据库供应商,但事实并非如此,因为它抛出了以下非常清楚的异常:

javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "ADDDATE": invalid identifier

以及查询跟踪:

(AddDate(t0.CREATION_DATE, ?, t0.EXPIRATION_DAYS) BETWEEN ? AND ?)).

如何使用 ORACLE 作为数据库来实现这一点?还是有更好的方法?

【问题讨论】:

  • function 直接通过,因为它正在调用显式 SQL 函数。
  • @BillyFrost 起初阅读了一些文档我虽然有一些使用 function 的名称函数将被转换为特定的供应商函数......但是你对 function 的方式是正确的,谢谢:)

标签: oracle jpa oracle10g criteria-api


【解决方案1】:

Hibernate 中似乎有 @Formula 注释提供了我正在寻找的功能,但是在我正在使用的特定实现中,JPA 中也没有这样的东西(eclipselink)。

我想避免声明特定函数的必要性,但不幸的是我这样做了,首先我在Oracle中声明函数ADD_DAYS如下:

create or replace function ADD_DAYS(dateValue DATE, daysValue NUMBER)
return DATE is
begin
    return dateValue + daysValue;
end;

然后我使用criteriaBuilderfunction 方法调用此函数,并将函数名称、oracle 函数返回的对象类型以及我定义的两个参数、带有日期的列和作为参数传递包含要添加的日期的列:

criteriaBuilder.function("ADD_DAYS", Date.class, Object.get("creationDate"), Object.get("expirationDays"))

【讨论】:

    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 2012-03-15
    • 2020-11-20
    • 2020-11-10
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多