Multi-tenancy and EntityManager.find method

I have a question about HHH-16179 and HHH-16626. HHH-16626 adds a test to TenantIdTest (testEntityManagerHint) and this test “expect” to find record2 by a find when tenant session is set to ‘mine’, but record2 is from tenant ‘yours’. This behavior is noticed and a comment is added: “Session seems to not apply tenant-id on #find”. But I think this should fail. I did some tests with and without commit: 0b5e27d133966b9846dfed00cab03204fa2c1897 (HHH-16179). Without this commit (HHH-16179) record2 can not be found as (I think) expected and then of course HHH-16626 test fails.

Is this correct behavior? It looks like a behavior change.

Did you check how Hibernate 5.6 behaves? I’m pretty sure it behaves the same way.

I tested all versions from 6.0.0 until HHH-16179 and Hibernate behaves the same, the find does only returns records from the current tenant id. From 6.0.0 multi tenancy works a little bit different, but I try to make a test as soon as possible.

You should try out version 5.6. In 6.0 we introduced a change which was decided to have been “wrong” and was reverted with HHH-16179.

I make a test for 5.6 as soon as possible, that was what I meant. But what I don’t understand is the decision that when I’m using multi-tenancy (In my case Shared Database, Shared Schema) and I use the find method and request an id from another tenant (not the current tenant) that I get a result. But when I use the createQuery method and request the same id it fails. It even looks like a security problem? To access all data there is something like an admin mode for this kind of actions?

You need to know the id of the thing you want to access and have an endpoint that passes through the id without doing any security checks. If your app is like that, then there is a security problem, but it’s in your app. We try to retain backwards compatibility, that’s why the application of Hibernate filters in the find() call was reverted. It could be that multi-tenancy in Hibernate 5.6 was implemented differently, but in 6 is implemented through filters. If that is the case, then it’s a bug, otherwise, it’s just “by design”.

Shared Schema doesn’t seem to be implemented in Hibernate 5, so there is no comparison.
Backwards compatibility forcing the removal of filters on a find() is understandable, but the fact that Shared Schema was implemented through filters shouldn’t affect it’s functionality, which is showing data of just a single tenant.
By removing this tenant filter on find(), data may leak, which I would consider a security issue. I would expect there to be an exception for the tenant filter.

From an implementation POV it’s not hard to do that, but I think you should start a discussion about this on our chat platform Zulip to see if you can convince others as well.

We were actually thinking about offering an option in IdentifierLoadAccess to control whether filters should be applied or not or even a session wide config for the same purpose.

Bring up the topic on our chat and let’s see what others think.

I also did some testing with 5.6 and indeed there is no support for Shared Schema (as mentioned: Hibernate ORM 5.6.15.Final User Guide 19.4, DISCRIMINATOR). To achieve Shared Schema in 5.6 most implementations are using filtering and indeed they have all the problem that find() can not be filtered (for example Dynamic Multi Tenancy with Spring Boot, Hibernate and Liquibase Part 5: Implementing the Shared Database with Discriminator Column pattern using Hibernate Filters | Callista). So I agree that filtering should also not work on find() in Hibernate 6.x because it ‘breaks’ the API, but in case we use the new @TenantId in 6.x I expect that find() only returns items from the current tenant. That @TenantId is implemented with filters is (I think) an implementation issue.

Yes, this is exactly the problem.
When they implemented the ticket HHH-16179 they removed the loadQueryInfluencers.getEnabledFilters(), from the:
org.hibernate.loader.ast.internal.LoaderSelectBuilder#applyFiltering

The tenant partition filter is implemented only on version 6, but they rolled back the implementation on version 6.2

You can follow HHH-16830 - apply filters to 'find()' method by gregoriopalama · Pull Request #7722 · hibernate/hibernate-orm · GitHub and [HHH-16830] - Hibernate JIRA for details.