java - 如何使用 CriteriaQuery 选择抽象服务中的通用对象列表

标签 java hibernate jboss7.x ejb-3.2

尝试采用此方法并优化性能:

public T getByPrimaryKey(PK id) {
    T entity = getEntityManager().find(getEntityClass(), id);
    if(entity != null) {
        preProcessEntity(entity);
    }
    fireEvent(entity, IEntityEventService.Event.READ, null);
    return entity;
}

原因是我们在很多领域都可以根据 native 查询获取 Id 列表,并且它们是单独处理的,从而导致 Hibernate 创建单个查询。我想让 Hibernate 一次获取所有这些。

public List<T> getEntitiesByPrimaryKey(List<PK> pks) {
    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<T> cq = cb.createQuery(getEntityClass());
    Root<T> root = cq.from(getEntityClass());

    Metamodel m = getEntityManager().getMetamodel();
    EntityType<T> T_ = m.entity(getEntityClass());

    Path<T> keyPath = root.get(T_.getDeclaredId(getEntityClass()));
    cq.select(root);
    cq.where(keyPath.in(pks));

    List<T> entities = getEntityManager().createQuery(cq).getResultList();
    if(entities != null) {
        for (T entity : entities) {
            preProcessEntity(entity);
            fireEvent(entity, IEntityEventService.Event.READ, null);
        }
    }
    return entities;
}

我不知道从这里该去哪里。主键不保证是整数,但几乎肯定是。

最佳答案

解决方法如下:

    //grabs the primaryKeyClass from generic type argument list (this was AbstractService<PK, T>)
    @SuppressWarnings("unchecked")
    protected Class<PK> primaryKeyClass = (Class<PK>) GenericTypeResolver.resolveTypeArguments(getClass(), AbstractService.class)[0];

    protected Class<PK> getPrimaryKeyClass() {
        return primaryKeyClass;
    }

    //code to retrieve generic list based on primary key
    public List<T> getEntitiesByPrimaryKey(List<PK> pks) {
        if(pks == null || pks.size() == 0)
            return new ArrayList<T>();

        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<T> cq = cb.createQuery(getEntityClass());
        Root<T> root = cq.from(getEntityClass());

        Metamodel m = getEntityManager().getMetamodel();
        EntityType<T> T_ = m.entity(getEntityClass());
        Path<PK> keyPath = root.get(T_.getId(getPrimaryKeyClass()));

        cq.select(root);
        cq.where(keyPath.in(pks));

        List<T> entities = getEntityManager().createQuery(cq).getResultList();
        if(entities != null) {
            for (T entity : entities) {
                preProcessEntity(entity);
                fireEvent(entity, IEntityEventService.Event.READ, null);
            }
        }
        return entities;
    }

关于java - 如何使用 CriteriaQuery 选择抽象服务中的通用对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27112701/

相关文章:

java - JNA - CreateToolhelp32Snapshot 未返回所有 DLL

java - 如何强制用户输入固定数量的int数字?

java - Hibernate映射异常

java - 如何在hql查询中将列的枚举类型转换为整数?

java - JBoss7 : loader constraint violation with ReastEasy and httpclient with custom HttpRequestInterceptor

Java EE 6 安全和重定向

java - 错误: The method ofMonths(int) is undefined for the type Period

java - 使用角色JAVA访问时Spring Security 403错误

java - JPA @OrderBy 注解 - 排序字符串

java - 在 JBoss EAP 6.1 中将池分配给特定的无状态 Bean