jemag
jemag

Reputation: 179

Hibernate manyToOne filter on base entity

I have an entity "Event" that has a ManyToOne relationship with the entity "Organization". So an Organization can have multiple events.

What I originally wanted to do was to filter the entity Event using a property of the Organization entity. So basically when I fetch events, only return the events that have an Organization.code= :codeParam.

To accomplish that I implemented a hibernate filter with :

@FilterDef(name="codeFilter", parameters=@ParamDef( name="codeParam", type="string" ) )

...

@ManyToOne
@JoinColumn(name="Organization_Id")
@Filter(name="codeFilter", condition=" code = :codeParam")
private Organization organization;

...

Filter hibernateFilter = sess.enableFilter("codeFilter");
hibernateFilter.setParameter("codeParam", "hola");

Unfortunately according to a post from the Hibernate Team on the hibernate forums, this is not possible :

A Hibernate data filter does not change the multiplicity of an association. By definition it therefore does not filter many-to-one, one-to-one, or any load() or get() operation.

What is it supposed to do, return NULL instead of an instance? NULL does not mean FILTERED, it means NULL. You guys are using filters wrong.

So my question is : is there any way to filter the base entity ("Event") with a condition on the entity from a manyToOne relationship (Organization.code= :codeParam)?

I need this to be enforced every time there is a fetch of events, so a solution using the already existing hibernate filters or something similar would be greatly appreciated.

EDIT1: The question is a simple example of what needs to be done on a significantly bigger scale. Basically, we want to add security to all our Entities and their own nested Entities through the use of a globally defined filter on a Unix permissions row that all our tables have.

Upvotes: 4

Views: 2268

Answers (1)

Douglas
Douglas

Reputation: 5087

WARNING: Do not do this, it is dependent on Hibernate internals and prone to breaking on schema changes, and possibly on variations in individual query setup.

Set Hibernate to show its generated sql, run the query you want to filter (in this case, loading some Event objects), and check what name it assigns to the join used for fetching the related Organization. For example, the generated sql might include inner join Organization someNameHere on this_.Organization_Id = someNameHere.OrganizationId. Then apply the filter, not to the association, but to the Event class, with condition "someNameHere.code = :codeParam".

This is, unfortunately, the only way I've been able to find to filter one class by the properties of an associated class.

I'm trying to make a more robust solution, but it's a complex issue and I'm still in the research stage for that. I expect it will use code generation (through an annotation processor) and programmatic modification of Hibernate's mapping information on startup, but I'm not sure what else yet.

Upvotes: 1

Related Questions