Hello all,
recently we are working on multi-tenancy with a shared schema approach. We came up to the solution that Hibernate's filters could be useful in this scenario. An in fact it works like a charm... Except one problem we have:
We only have two filters defined. When the user request a hibernate session these filters are both enabled or disabled if the user is a standard user (enable) or an admin (disable => sees anything).
No I have the effect that all filters are used on all entities that have a @Filter annotation.
The filter definitions are in the package-info.properties file:
Code:
@FilterDefs({
@FilterDef(name = HibernateConstants.MULTI_TENANCY_FILTER_NAME,
parameters = @ParamDef(name = HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, type = "string"),
defaultCondition = "..."),
@FilterDef(name = HibernateConstants.MULTI_TENANCY_EVENT_FILTER_NAME,
parameters = @ParamDef(name = HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, type = "string"),
defaultCondition = "...")
})
Now there are a bunch of entities like the following which uses the basic multi-tenancy filter:
Code:
@Entity
@Table(name = "AccessObject")
@Audited
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@OrderIssuer(events = { SystemEvent.ENTITY_UPDATED, SystemEvent.ENTITY_DELETED })
@Filter(name = HibernateConstants.MULTI_TENANCY_FILTER_NAME)
public abstract class AccessObject extends OLEntity implements LocationAware, TenantAware
{
...
}
There is only one other which uses the second filter:
Code:
@Entity
@Table(name = "Event")
@org.hibernate.annotations.Table(
appliesTo = "Event",
indexes={
@Index(name="Event_01", columnNames={Event.PROPERTY_LOG_DATE}),
@Index(name="Event_02", columnNames={Event.PROPERTY_LOG_DATE, Event.PROPERTY_IDENTIFIER})
})
// @Audited => no audit with concerns of performance and because events are not very likely to be changed at all
@Viewable
@PublishEvents(events = { SystemEvent.ENTITY_CREATED }, properties = { Event.PROPERTY_EVENT_TYPE, Event.PROPERTY_SOURCE_TYPE, Event.PROPERTY_SOURCE_ID })
@Filter(name = HibernateConstants.MULTI_TENANCY_EVENT_FILTER_NAME)
public class Event extends BaseEntity
{
...
}
As mention both are activated be means of the users security context:
Code:
// Enforce security constraints
SecurityContext ctx = SecurityContextHolder.getContext();
if (ctx == null || ctx.isAdmin())
{
// if operator is admin or no operator is set or no context exists => allow any permissions
p_session.disableFilter(HibernateConstants.MULTI_TENANCY_FILTER_NAME);
}
else
{
// if operator is not admin => apply operator permissions
if (ctx.permittedClientIds().isEmpty())
{
p_session.enableFilter(HibernateConstants.MULTI_TENANCY_FILTER_NAME).setParameter(HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, "");
p_session.enableFilter(HibernateConstants.MULTI_TENANCY_EVENT_FILTER_NAME).setParameter(HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, "");
}
else
{
p_session.enableFilter(HibernateConstants.MULTI_TENANCY_FILTER_NAME).setParameterList(HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, ctx.permittedClientIds());
p_session.enableFilter(HibernateConstants.MULTI_TENANCY_EVENT_FILTER_NAME).setParameterList(HibernateConstants.MULTI_TENANCY_FILTER_PARAM_NAME, ctx.permittedClientIds());
}
}
But since I defined the second filter any query of the entities annotated to use only the first filter will be modified with the second filter too.
Is this a known or maybe intended behavior?
EDIT:
Seems as if the second filter definition is moved to the entity it works as expected. Maybe has something to do with defining the annotations on package level?
Kind regards,
Sebastian