JPA标准从实体对象层次结构(通常)计算特定子项

时间:2013-11-02 06:19:00

标签: java hibernate java-ee jpa criteria

我有以下情况:

@Entity
public class Definition {
   ...
   @OneToMany(mappedBy = "productDefinition", cascade = { CascadeType.ALL })
   @OrderBy("name")
   private Set<Product> products = new LinkedHashSet<>();
   ....
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Product {
  ...
  @ManyToOne(fetch = FetchType.LAZY)
  private Definition productDefinition;
  ...
}

@Entity
public class FancyProduct extends Product {
}

@Entity
public class PlainProduct extends Product {
}

在我的DAO中,我有一个通用的标准查询,超过definitions,应该提取每种特定类型产品的计数(在这种情况下分别是FancyProductPlainProduct)。当我在代码中执行setJoin时,如下所示:

SetJoin<T, ?> setJoin = from.joinSet(attributeName, JoinType.LEFT);

更新

我试图提取查询的创建方式。它是从更广泛的背景中提取出来的,所以我希望它有任何意义:

// The result class is DefinitionDTO a DTO class 
CriteriaQuery<R> query = builder.createQuery(resultClass);
// select from - the entity class (Definition in my case)
Root<T> from = query.from(entityClass);
...
SetJoin<T, ?> setJoin = from.joinSet(attributeName, JoinType.LEFT);
// add type restriction
Class<?> manyElemTypeClass = attribute.getManyElemTypeClass();
if (manyElemTypeClass != null &&!Modifier.isAbstract(manyElemTypeClass.getModifiers()))     {
                predicates.add(builder.or(setJoin.type().in(manyElemTypeClass), setJoin.type().isNull()));
            }
            Expression<Long> count = builder.countDistinct(setJoin);
            count.alias(attributeName);
            // select count
            countSelections.add(count);
            // order by count
            orderByExpressions.add(count);
            // always restrict data based on join
            wherePath = setJoin;
  ...

所以当我只有一个孩子的情况下工作,所以在这种情况下,如果我只需要PlainProduct,但只要我将FancyProduct添加到结果dto,它就不再有效了。

生成的SQL如下所示:

select
    filmmateri0_
    count(distinct producepro3_.id) as col_6_0_,
from
    ProductDefinition filmmateri0_
left outer join
    (
        select
            id,
            creationDate,
            entityVersion,
            key,
            lastChangedDate,
            deleted,
            description,
            produceMaterial_id,   
            1 as clazz_ 
        from
            FancyProduct
        union
        all select
            id,
            creationDate,
            entityVersion,
            key,
            lastChangedDate,
            deleted,
            description,
            produceMaterial_id,
            2 as clazz_ 
        from
            PlainProduct
    ) producepro3_ 
        on filmmateri0_.id=producepro3_.produceMaterial_id

因此,在这种情况下,它只会计算Product类型的所有元素。有没有办法指出特定叶子上的setJoinjoin

0 个答案:

没有答案