I went with a work-around. Others have detailed the steps. The main ones are:
- Add a custom (web) servlet filter that enables a (pre-defined) Hibernate (JPA) filter and sets its parameters. This takes care of enforcing tenant boundaries on all "read" operations (queries).
- Add a custom EmptyInterceptor that ensures the create (insert / save), update (flush-dirty), and delete operations all honor the tenancy boundaries.
Wire the whole thing up with a context that is tenant aware. In my case I use Spring and Spring Security for that. Overall it turned out to be pretty straight forward and also pretty easy to write tests for it. The trickiest part is that different entities have different rules for both kinds of filtering. For example, the Account entity - which holds the tenant details and acts as the "owner" object for all the other tenant-specific entities - needs a special filter since rather than filtering on ownerId as we (more or less) do for all the other entities, we filter on the id of the account object itself. But that's the nature of the domain. Anyway it works well and amounted to just a few relatively small classes and some annotations on the entities. HTH. |