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

Steve Ebersole steve at hibernate.org
Fri Jun 1 12:56:41 EDT 2012


Hi Rob,   overall I am OK with the proposal.

Some comments inline

On Thu 31 May 2012 03:32:25 PM CDT, David Mansfield wrote:
>> 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.

To be honest, I still think an embedded hint for the alias placement is 
a good idea.  There is a lot of chicanery in Hibernate code to try to 
figure out the correct place to put aliases in sql fragments.  
Something like this removes that ambiguity:

@OneToMany(mappedBy="club")
@Filters({
    @Filter(name="iqMin", table="ZOOLOGY_HUMAN", 
condition="{alias}.HUMAN_IQ >= :min"),
    @Filter(name="pregnantMembers", table="ZOOLOGY_MAMMAL", 
condition="{alias}.IS_PREGNANT=1")
})
private Set<Human> members = new HashSet<Human>();

Its really 2 different concerns.


> 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.

It would need to allow a mix of both I think.  The Class reference is a 
good alternative for inheritance as initially discussed here.  But 
another place this comes up is in regards to SecondaryTables, and there 
we would need to know the table name.


--
steve at hibernate.org
http://hibernate.org


More information about the hibernate-dev mailing list