[hibernate-dev] Pull request for HHH-2394 (Support filter tag in subclass)

David Mansfield hibernate at dm.cobite.com
Thu May 31 16:32:25 EDT 2012


I'm no hibernate guru, but I have some comments below:

On 05/30/2012 05:42 PM, Rob Worsnop wrote:
> https://github.com/hibernate/hibernate-orm/pull/339
>
> It seemed that the challenge to overcome was that Hibernate did not
> know which aliases to use when generating the where clauses for
> filters. When filters are not allowed on subclasses (current
> situation), the alias for the root entity is used for all where
> clauses. So when FilterHelper is asked to render the filters, it does
> so with a single alias string.

> So my changes revolve around two themes:
>
> 1. Remembering the filter's associated table so that we can generate
> an appropriate alias. This was done by replacing the name->condition
> map with a list of FilterConfiguration objects. This is a new class
> and includes a qualified table name (as well as the name and
> condition, of course).
>
> 2. Passing a callback (instead of the alias string) to
> FilterHelper.render() that allows it to generate an appropriate alias
> for each filter, depending on table name. The callback is an
> implementation of a new interface, FilterAliasGenerator. The
> implementation varies by context.
The same problem exists in Criteria queries (HHH-1161)  when using the 
sqlRestriction.  In that use case, one uses the string '{alias}' as a 
placeholder in the SQL, and the engine replaces it, however as with your 
problem, it always replaces with the subclass alias, and therefore 
cannot be used to create a restriction on any superclass properties.

It seems a more generic approach to the '{alias}' syntax which allows 
for, perhaps, '{entityName.alias}' (e.g. 
'{com.example.Mammal.alias}.is_pregnant = 1' would work, then your 
filter conditions wouldn't need the "table" attribute, and the fix would 
possibly be extensible for HHH-1161.

Alternatively, there are already some annotations which take an entity 
directly (such as @ManyToOne), as a class reference, which is way more 
typesafe and refactoring friendly.  So instead of 
"table='ZOOLOGY_MAMMAL'" you could have "entity=Mammal.class".  This 
would require more bookeeping on the implementation side, but would be a 
superior abstraction IMHO.
>
> Where filters are applied to entities, we know the table name. When
> filters are applied to collections we do not. My solution to this is
> potentially controversial and I'd be interested in hearing
> alternatives to it. I have expanded the @Filter annotation to include
> a table name. This is an optional element because it makes no sense
> when @Filter is applied directly to an entity. That's what I don't
> like about this idea.
>
> For example:
>
> 	@OneToMany(mappedBy="club")
> 	@Filters({
> 		@Filter(name="iqMin", table="ZOOLOGY_HUMAN", condition="HUMAN_IQ>= :min"),
> 		@Filter(name="pregnantMembers", table="ZOOLOGY_MAMMAL",
> condition="IS_PREGNANT=1")
> 	})
> 	private Set<Human>  members = new HashSet<Human>();
>
> This is excerpted from here:
> https://github.com/rworsnop/hibernate-orm/blob/HHH-2394/hibernate-core/src/matrix/java/org/hibernate/test/annotations/filter/subclass/joined/Club.java
>
> Thoughts?
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev


More information about the hibernate-dev mailing list