CurrentTenantIdentifierResolver and MultiTenantConnectionProvider don't seem to get picked up from the BeanContainer
Description
Attachments
Activity

Yoann Rodière October 7, 2024 at 8:02 AM
I don’t know the motivation for Search or for Quarkus to override the default (and IMO better) behavior of ORM, but I will follow up on this with .
In particular, I’m struggling to see why Quarkus overrides this, and so perhaps it’s simply unnecessary. If so, and if we can start using
JpaCompliantLifecycleStrategy
in Quarkus, then I can drop my objections to the linked pull request.
Starting a conversation on Zulip, because I have a feeling it will be long and painful: https://hibernate.zulipchat.com/#narrow/stream/132094-hibernate-orm-dev/topic/JPA-compliant.20CDI.20and.20HHH-15422

Gavin King October 4, 2024 at 6:40 PM
Oh, I realized that you guys are probably thinking that these things are just completely bog-standard CDI beans that are discovered, registered, and instantiated completely by CDI with no involvement of Hibernate at all.
But while this approach might be OK for, say CurrentTenantIdentifierResolver
which is a very simple object, it doesn’t work in general—for example, it doesn’t work for entity listeners, attribute converters, Generator
s, nor, in general for ConnectionProvider
s:
the CDI container doesn’t discover these things; they’re configured via annotations, and,
furthermore, some of them need access to the Hibernate
ServiceRegistry
when they’re instantiated.
So what I’m trying to do here is find an approach which works generically, for all these sorts of components, not just for two of them, and that’s easy because it’s already defined in the JPA spec, and already implemented by JpaCompliantLifecycleStrategy
.
Now, having said all that, I just noticed from the code that in fact we never actually use ContainerManagedLifecycleStrategy
in ORM itself, rather, we always use the JpaCompliantLifecycleStrategy
. Digging further I found that:
according to , WildFly does not override this behavior, but
Hibernate Search apparently does, and forces the use of
ContainerManagedLifecycleStrategy
, and, similarly,Quarkus also forces the use of
ContainerManagedLifecycleStrategy
.
I don’t know the motivation for Search or for Quarkus to override the default (and IMO better) behavior of ORM, but I will follow up on this with .
In particular, I’m struggling to see why Quarkus overrides this, and so perhaps it’s simply unnecessary. If so, and if we can start using JpaCompliantLifecycleStrategy
in Quarkus, then I can drop my objections to the linked pull request.

Gavin King October 4, 2024 at 12:11 PMEdited
so these contracts can safely be constructed through the bean container.
You can only do that while CDI is in the process of bootstrapping itself. Which means that Hibernate and CDI would have to be bootstrapped simultaneously.
It's not possible to register a new CDI bean after CDI has already started, since CDI validates all bean inter-dependencies during the startup phase, and if a bean is missing, it reports an error.
Currently this works because Hibernate starts before CDI, due to the whole problem with ClassTransformer
, but that’s something we’re proposing to change because it causes problems.

Christian Beikov October 4, 2024 at 11:50 AM
Whatever we come up with for the JPA spec, we need a split in the bootstrap similar to what we have in Hibernate ORM. The first phase can’t use CDI and uses a temporary class loader to create the ClassTransformer
whereas the second phase can fully leverage CDI.
The key thing to recognize is that there is no need to instantiate services like ConnectionProvider
and MultiTenantConnectionProvider
in the first bootstrap phase, so these contracts can safely be constructed through the bean container.

Gavin King October 4, 2024 at 11:28 AM
On the other hand, there is a well-defined way in CDI and Jakarta EE to allow components like MultiTenantConnectionProvider
and CurrentTenantIdentifierResolver
to have beans injected into them, without themselves needing to be beans.
This mechanism is also described in section 3.9 of the JPA spec.
That is the correct approach to use here.
Details
Assignee
Yanming Zhou (quaff@github)Yanming Zhou (quaff@github)Reporter
Jens SchauderJens SchauderFix versions
Priority
Major
Details
Details
Assignee

My expectation is that when an external BeanContainer is configured Hibernate would ask the BeanContainer for instances of
CurrentTenantIdentifierResolver
andMultiTenantConnectionProvider
This doesn’t work. I have to explicitly set these.
I just to try to make this work.
And it does work in the current state
But it requires explicit setting of the
MULTI_TENENT_IDENTIFIER_RESOLVER
viaIs there a reason, why Hibernate doesn’t ask the
BeanContainer
for instances of this class? Or is this an oversight/bug/missing feature?Based on the referenced projects I verified that for example a entity listener is pulled from the
BeanContainer
backed by a SpringApplicationContext
There are also variants of the projects in the same repository which demonstrate the same problem with the connection provider.