JPA中所有NamedQueries的列表

时间:2012-09-27 05:54:32

标签: hibernate jpa named-query

我想在我的应用程序中获取所有NamedQueries的列表,并且我还想在运行时一般性地调用它们。是否有选项可以获取列表以及某种元数据(一般来说是某种反射)?

另一个Thread为NHibernate提供了某种解决方案......即使使用Hibernate作为实现,也无法在JPA中找到类似的解决方案。

提前谢谢 El Subcomandante

3 个答案:

答案 0 :(得分:3)

我认为在内置的一个步骤中没有任何东西可以做到这一点。但你可以使用JPA2中的元模型,加上一些简单的反思:

private static Set<NamedQuery> findAllNamedQueries(EntityManagerFactory emf) {
    Set<NamedQuery> allNamedQueries = new HashSet<NamedQuery>();

    Set<ManagedType<?>> managedTypes = emf.getMetamodel().getManagedTypes();
    for (ManagedType<?> managedType: managedTypes) {
        if (managedType instanceof IdentifiableType) {
            @SuppressWarnings("rawtypes")
            Class<? extends ManagedType> identifiableTypeClass = managedType.getClass();

            NamedQueries namedQueries = identifiableTypeClass.getAnnotation(NamedQueries.class);
            if (namedQueries != null) {
                allNamedQueries.addAll(Arrays.asList(namedQueries.value()));
            }

            NamedQuery namedQuery = identifiableTypeClass.getAnnotation(NamedQuery.class);
            if (namedQuery != null) {
                allNamedQueries.add(namedQuery);
            }
        }
    }
    return allNamedQueries;
}

答案 1 :(得分:3)

Tom Anderson的回答有一个错误:它试图在JPA实现的ManagedType类上找到注释,而不是实际的实体类。这是更正后的版本。

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.EntityManagerFactory;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.metamodel.EntityType;

private static Set<NamedQuery> findAllNamedQueries(EntityManagerFactory emf) {
    Set<NamedQuery> allNamedQueries = new HashSet<NamedQuery>();

    Set<EntityType<?>> entityTypes = emf.getMetamodel().getEntities();
    for (EntityType<?> entityType : entityTypes) {
        Class<?> entityClass = entityType.getBindableJavaType();

        NamedQueries namedQueries = entityClass.getAnnotation(NamedQueries.class);
        if (namedQueries != null) {
            allNamedQueries.addAll(Arrays.asList(namedQueries.value()));
        }

        NamedQuery namedQuery = entityClass.getAnnotation(NamedQuery.class);
        if (namedQuery != null) {
            allNamedQueries.add(namedQuery);
        }
    }
    return allNamedQueries;
}

这仍然是纯粹的JPA2。

答案 2 :(得分:0)

我不明白这个问题,你已经给出了解决方案? 您只需扫描类并使用反射。

这为您提供了课程的所有注释。 http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getAnnotations%28%29

现在遍历该列表以获取NamedQueries。 我想您不必扫描所有类,只要您阅读persistance.xml文件并且只扫描您定义的实体就足够了。

这是一个详细的例子: http://tutorials.jenkov.com/java-reflection/annotations.html

您应该能够将Annotation强制转换为NamedQuery,然后只需访问名称/查询属性。

塞巴斯蒂安