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