The problem with using filters with @ManyToOne
join comes from the following.
I'm referring to Hibernate 4.3.10 as this is what I have to look at.
The relevant SQL fragment is generated by class org.hibernate.engine.internal.JoinSequence
, method 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 );
Depending on the defined relationship join.getAssociationType()
returns CollectionType
or EntityType
.
The former stands for declaration like:
@OneToMany
private List<MyEntity> myEntities;
The latter stands for this one:
@ManyToOne
private MyEntity myEntity;
In the first case this method is used:
@Override
public String getOnCondition(
String alias,
SessionFactoryImplementor factory,
Map enabledFilters,
Set<String> treatAsDeclarations) {
return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations );
}
while in the second case the method looks like:
@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 );
}
}
This means that:
- when we have a list of referenced sub-entities in definition of an
entity, filter is unconditionally applied.
- when we have a single referenced sub-entity, filter is applied
when certain conditions are (not) met.
Based on the code, I think that filters can be applied in case of @ManyToOne
relationship when:
- in referenced entity we use a field
which is not a primary key, or
- TREAT operator is used (see, for example, here or here)
@ManyToOne
. That's my problem :/ In the documentation it only talks about@OneToMany
andCollection
. Do you if Filter is able even for ManyToOne relationship? – Burks