@ManyToOne
結合でフィルターを使用する場合の問題は、次の原因によるものです。これが私が見なければならないものであるため、私はHibernate4.3.10を参照しています。
関連するSQLフラグメントは、クラスorg.hibernate.engine.internal.JoinSequence
、メソッドによって生成されtoJoinFragment
ます。
/**
* Generate a JoinFragment
*
* @param enabledFilters The filters associated with the originating session to properly define join conditions
* @param includeAllSubclassJoins Should all subclass joins be added to the rendered JoinFragment?
* @param withClauseFragment The with clause (which represents additional join restrictions) fragment
* @param withClauseJoinAlias The
*
* @return The JoinFragment
*
* @throws MappingException Indicates a problem access the provided metadata, or incorrect metadata
*/
public JoinFragment toJoinFragment(
Map enabledFilters,
boolean includeAllSubclassJoins,
String withClauseFragment,
String withClauseJoinAlias) throws MappingException {
...
final String on = join.getAssociationType().getOnCondition( join.getAlias(), factory, enabledFilters, treatAsDeclarations );
定義された関係に応じて、またはをjoin.getAssociationType()
返します。CollectionType
EntityType
前者は次のような宣言を表します。
@OneToMany
private List<MyEntity> myEntities;
後者はこれを表します:
@ManyToOne
private MyEntity myEntity;
最初のケースでは、この方法が使用されます。
@Override
public String getOnCondition(
String alias,
SessionFactoryImplementor factory,
Map enabledFilters,
Set<String> treatAsDeclarations) {
return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations );
}
2番目のケースでは、メソッドは次のようになります。
@Override
public String getOnCondition(
String alias,
SessionFactoryImplementor factory,
Map enabledFilters,
Set<String> treatAsDeclarations) {
if ( isReferenceToPrimaryKey() && ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) ) {
return "";
}
else {
return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations );
}
}
この意味は:
- エンティティの定義に参照されているサブエンティティのリストがある場合、フィルターは無条件に適用されます。
- 参照されるサブエンティティが1つしかない場合、特定の条件が満たされた(満たされていない)ときにフィルターが適用されます。
コードに基づいて、次の場合に@ManyToOne
関係の場合にフィルターを適用できると思います。
- 参照されるエンティティでは、主キーではないフィールドを使用します。
- TREAT演算子が使用されます(たとえば、を参照してください)。ここまたはここ)