私は基本的に初めてCriteria APIを使用しています。これは、ジェネリック ビルダーのクエリを抽象化することです。
public TypedQuery<T> newQuery( Manager<?,T> manager )
{
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
Class<T> genericClass = ( Class<T> ) ( ( ParameterizedType ) manager.getClass().getGenericSuperclass() ).getActualTypeArguments()[1];
CriteriaQuery<T> criteriaQuery = builder.createQuery( genericClass );
Root<T> root = criteriaQuery.from( genericClass );
...
}
デフォルトでは、この呼び出しにより、エンティティで見つかったすべての関係に対してcriteriaQuery.from( genericClass );
SQL が生成されます。INNER JOIN
これは問題です。すべてのリレーションシップが null (DBNULL
または外部キーを使用せず、無効な参照を持つ DB) である場合、これらのエンティティが結果リストに表示されず、事実上間違った検索結果が生成されるためです。
例はここにあります: JPA Criteria query Path.get left join is it possibile
このクラス/メソッドによってインスタンス化されたクエリで発生したいことは、エンティティのすべての関係がここgenericClass
で、次のようにマップされることです。optional = true
@ManyToOne( FetchType.EAGER, optional = true )
@JoinColumn( name = "CLOSE_USER_ID", referencedColumnName = "USER_ID" )
private User closer;
LEFT (OUTER) JOIN
の代わりにSQL を生成しますINNER JOIN
。
質問:
これを行うための標準的なJPQの方法はありますか? もしそうなら、どのように?
PS: 一般に、具体的な型を事前に知る方法はないため、必要なことを達成できる唯一の方法は、ある種のメタモデルを使用して手動で結合を生成することです (これは避けたいと思います)。
EclipseLink 2.3を使用しています