针对不同实体的CriteriaQuery

时间:2016-03-23 22:14:07

标签: java jpa

我有一个非常基本的问题,但无法找到正确的解决方案。我想阅读JPAEntity的所有记录,使用CriteriaQuery,它只分别引用了JPAEntity的类,它应该适用于不同的JPAEntites。

以下代码有效,它可以实现我的目标:

private void test(Field jpaField) {
    List l;
    final Class c = jpaField.getType();

    final CriteriaQuery criteriaQuery = em.getCriteriaBuilder().createQuery(c);
    criteriaQuery.select( criteriaQuery.from( c ) );
    l = em.createQuery(criteriaQuery).getResultList();

    ...
}

但是我收到很多关于类型安全的警告。我尝试了以下更正来解决这个问题,同时保持通用:

private void test(Field jpaField) {
    List<?> l;
    final Class<?> c = jpaField.getType();

    final CriteriaQuery<?> criteriaQuery = em.getCriteriaBuilder().createQuery(c);
    criteriaQuery.select( criteriaQuery.from( c ) );
    l = em.createQuery(criteriaQuery).getResultList();

    ...
}

但现在我收到有关不匹配类型的错误。我想我必须确保createQuery(c)和(c)使用相同的类型。但我不知道如何。有谁知道如何正确使用这种模式?

感谢您的任何提示。

最好的问候,Dominic

2 个答案:

答案 0 :(得分:1)

正如所指出的,通用findAll方法的签名是

<T> List<T> findAll(Class<T> entity)

我认为概念化的棘手部分是Class<T> entity。但是,如果你看一下createQuery的签名,你会发现它基本相同:

<T> CriteriaQuery<T> createQuery(Class<T> resultClass)

因此,通用findAll方法的编写如下:

public <T> List<T> findAll(Class<T> entity) {
    CriteriaQuery<T> q = em.getCriteriaBuilder().createQuery(entity);
    q.select(q.from(entity));
    return em.createQuery(q).getResultList();
}

像这样使用:

findAll(entity.getClass());

您不能传递实体本身的泛型方法,因为它是运行时对象,而泛型是编译时限制。

答案 1 :(得分:0)

这是一个方法问题。也许你可以在你的方法之外调用getType()?

 private <T> List<T> test(Class<T> jpaFieldClass) ....