Java 为未知实体类型生成常规LocalDate JPA条件

Java 为未知实体类型生成常规LocalDate JPA条件,java,jpa,generics,Java,Jpa,Generics,我正在尝试构建一个超级通用的JPA查询生成器,它采用一些通用的过滤器,并为JPA查询通用地构建条件。换句话说,我希望它用于任何类型实体的日期过滤 例如,我需要一个方法,该方法获取一些通用实体信息,并为LocalDate创建一个谓词。为了描述这一点,最好展示一下我目前所拥有的: public class DatePredicateBuilder { private final String dateAttribute; public DatePredicateBuilder(St

我正在尝试构建一个超级通用的JPA查询生成器,它采用一些通用的过滤器,并为JPA查询通用地构建条件。换句话说,我希望它用于任何类型实体的日期过滤

例如,我需要一个方法,该方法获取一些通用实体信息,并为
LocalDate
创建一个谓词。为了描述这一点,最好展示一下我目前所拥有的:

public class DatePredicateBuilder
{
    private final String dateAttribute;

    public DatePredicateBuilder(String attributeName)
    {
        this.dateAttribute = attributeName;
    }

    @Override
    public <ENTITY> Predicate getEndPredicate(
        CriteriaBuilder criteriaBuilder,
        final Root<ENTITY> data,
        final EntityType<ENTITY> entityType,
        final LocalDate endDate)
    {
        return criteriaBuilder.ge( 
            data.get(entityType.getSingularAttribute(dateAttribute)),
            criteriaBuilder.literal(endDate)));
    }
}
公共类DatePredicateBuilder
{
私有最终字符串属性;
公共DatePredicateBuilder(字符串attributeName)
{
this.dateAttribute=attributeName;
}
@凌驾
公共谓词getEndPredicate(
CriteriaBuilder CriteriaBuilder,
最终根数据,
最终EntityType EntityType,
最终本地日期(结束日期)
{
返回criteriaBuilder.ge(
data.get(entityType.getSingularAttribute(dateAttribute)),
criteriaBuilder.literal(endDate));
}
}
我想,你可以看到这里的目标是什么。我希望能够为实体上的任何属性构建一些
DatePredicateBuilder
类,并有一个方法为我构建相应的
谓词

我认为这不会编译,因为第一个参数(未知)的泛型类型与第二个(
LocalDate
)的泛型类型不匹配。我可以对
CriteriaBuilder.ge
方法调用进行调整:
data.get(…)
,但是现在
getSingularAttribute
调用失败了,因为它不知道该属性是
LocalDate
。这也是因为它是如此的通用,以至于我们只知道属性名

我不介意在需要的地方强制转换,因为我强制执行的属性应该是
LocalDate
(如果不是,则应该失败),但我不确定要转换什么来修复此问题。换句话说,这只适用于
LocalDate
,因此我们可以相应地进行假设

我将继续对它进行黑客攻击,看看是否至少可以将其编译,但如果您有任何想法,我将不胜感激。

如果您使用

,

然后,它应该正确编译,并通知实体类型本身您期望属性是什么,因此您的类型需求也由JPA框架验证

您的完整代码:

@Override
public <ENTITY> Predicate getEndPredicate(
    CriteriaBuilder criteriaBuilder,
    final Root<ENTITY> data,
    final EntityType<ENTITY> entityType,
    final LocalDate endDate)
{
    return criteriaBuilder.greaterThanOrEqualTo( 
        data.get(entityType.getSingularAttribute(dateAttribute, LocalDate.class)),
        criteriaBuilder.literal(endDate)));
}
@覆盖
公共谓词getEndPredicate(
CriteriaBuilder CriteriaBuilder,
最终根数据,
最终EntityType EntityType,
最终本地日期(结束日期)
{
返回criteriaBuilder.greaterThanOrEqualTo(
data.get(entityType.getSingularAttribute(dateAttribute,LocalDate.class)),
criteriaBuilder.literal(endDate));
}
编辑:
根据OP下面的评论,要使用的标准生成器方法也不是
ge
(因为它用于数字字段),而是
greaterThanOrEqualTo

尝试使用有帮助的
CriteriaBuilder
。不知何故,我在javadoc中没有注意到这一点。结果是
ge
调用仍然是错误的;改为使用
greaterThanOrEqualTo
进行修复,因为
ge
似乎专门用于数字。@如果您不介意,我将更新我答案中的代码,并更改您的问题的方法。这将改善从搜索中来到这里的人们的生活。