JPA Criteria API-使用ORACLE

时间:2018-08-09 15:23:36

标签: oracle jpa oracle10g criteria-api

我正在尝试使用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作为数据库来实现此目的?还是有更好的方法?

1 个答案:

答案 0 :(得分:0)

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;

然后,我使用criteriaBuilder的{​​{3}}方法调用此函数,并将函数名称,oracle函数返回的对象类型以及我定义的两个参数作为参数传递,日期和要添加日期的列:

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