次のような状況があります。
@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
これにより、特定のタイプの製品ごとにカウントを抽出する必要があります(この場合FancyProduct
はPlainProduct
それぞれ)。コードで 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;
...
したがって、子供が1人しかいない場合でも機能するため、この場合は必要なだけPlainProduct
ですが、結果のdtoにも追加するとすぐにFancyProduct
機能しなくなります。
生成された 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
したがって、この場合、 type のすべての要素をカウントするだけProduct
です。特定のリーフの子のsetJoin
toを指す方法はありますか?join