使用带有@ManyToOne
连接的过滤器的问题来自以下内容。我指的是 Hibernate 4.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 );
}
而在第二种情况下,该方法如下所示:
@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 );
}
}
这意味着:
- 当我们在实体定义中有引用的子实体列表时,将无条件地应用过滤器。
- 当我们有一个引用的子实体时,在满足(不)某些条件时应用过滤器。
根据代码,我认为可以在以下情况下应用过滤器@ManyToOne
:
- 在引用的实体中,我们使用不是主键的字段,或者
- 使用 TREAT 运算符(例如,参见这里或这里)