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

时间:2014-11-24 19:33:20

标签: 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;
}

原因是我们有许多领域可以获得基于本机查询的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;
}

我不知道从哪里开始。主键不保证是整数,但几乎可以肯定是。

1 个答案:

答案 0 :(得分:1)

以下是修正它的原因:

    //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;
    }