Thanks for the great questions Brian! Responses inline below.
On 8/5/25 12:17 PM, Brian Stansberry via wildfly-dev wrote:
On Tue, Aug 5, 2025 at 9:59 AM Scott Marlow
<scott.marlow.opensource(a)gmail.com> wrote:
Hello,
The Jakarta EE 11 Platform implementations must include
built-integration of Jakarta Persistence with the CDI bean manager
[1], allowing injection of a container-managed entity manager
factory using the annotation jakarta.inject.Inject. Also expected
is support for injecting
/EntityManager//CriteriaBuilder/PersistenceUnitUti/Cache/SchemaManager/Metamodel
as well. Note that SchemaManager can only be injected on WildFly
Preview since that is a new api included in Jakarta Persistence 3.2.
This is a really nice feature as it allows applications to rely
more on CDI for injection of persistence units/contexts (and other
contained Persistence types). Injecting the EntityManagerFactory
is typically used for application managed persistence contexts
(e.g. EntityManager) where the application deals with closing the
EntityManager instance when it wants to. An application managed
persistence context is almost the same thing as extended
persistence contexts except the Persistence container does not
manage it and application managed persistence contexts can also be
used in most EE components where as extended persistence contexts
are limited to use in Stateful Beans. Injecting an EntityManager
bean is equivalent to accessing a transaction scoped entity
manager (e.g. @PersistenceContext EntityManager myentitymanager).
Our work in progress implementation of ^ is being tracked via
WFLY-19554 <
https://issues.redhat.com/browse/WFLY-19554> [2] +
pull request <
https://github.com/wildfly/wildfly/pull/19088> [3].
List of WildFly test failures with this change:
1.
org.jboss.as.test.integration.jpa.packaging.PersistenceUnitPackagingTestCase
fails with:
"Cannot deploy scopedToEar.ear...
Caused by: org.jboss.weld.exceptions.DeploymentException:
WELD-001414: Bean name is ambiguous. Name mainPu resolves to
beans: [Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types: Object,
EntityManagerFactory, AutoCloseable, qualifiers: @Any @Default],
Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types: Object,
EntityManagerFactory, AutoCloseable, qualifiers: @Any @Default]]"}}}}
"
2. org.jboss.as.test.integration.jpa.initializeinorder.InitializeInOrderTestCase
fails with similar ear test failure caused by:
"WELD-001414: Bean name is ambiguous. Name pu1 resolves to beans:
[Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types:
EntityManagerFactory, Object, AutoCloseable, qualifiers: @Any
@Default], Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types:
EntityManagerFactory, Object, AutoCloseable, qualifiers: @Any
@Default], Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types:
EntityManagerFactory, Object, AutoCloseable, qualifiers: @Any
@Default]]"}
"
3. org.jboss.as.test.integration.jpa.packaging.PersistenceUnitWarPackagingTestCase
falis with similar ear test failure caused by:
"Caused by: org.jboss.weld.exceptions.DeploymentException:
WELD-001414: Bean name is ambiguous. Name mainPu resolves to
beans: [Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types:
EntityManagerFactory, Object, AutoCloseable, qualifiers: @Any
@Default], Configurator Bean [interface
jakarta.persistence.EntityManagerFactory, types:
EntityManagerFactory, Object, AutoCloseable, qualifiers: @Any
@Default]]"}}}}
"
4. The Jakarta EE 10 Platform TCK also has similar failures
in 10925 Persistence tests when run with the current [3] change
with WildFly.
Why are we getting test failures and how to address the failures?
[4] contains the EntityManagerFactory bean setup method that uses
the application supplied persistence unit name to name
the EntityManagerFactory bean. If we comment out the call to
"beanConfigurator.name(persistenceUnitMetadata.getPersistenceUnitName())"
the WELD-001414 error goes away. We aren't supposed to comment
that line of code out as per the [1] requirements which mention we
need to set the (EntityManagerFactory) "bean name given by the
name of the persistence unit".
I believe that we are getting the WELD-001414 error in EAR
deployments that contain duplicate persistence unit definitions
(e.g. ear/lib contains a jar with the same persistence.xml as is
also contained in subdeployments). Gavin King asked me a good
question as to why WildFly is allowing duplicate persistence unit
definitions in application deployments. A fair question
Why do we allow it?
One answer is for backward compatibility that I think started
with JBoss
AS 5 and the EJB3 project. Also the initial Jakarta EE 8+ TCKs included
duplicate persistence unit definitions (same as the EE TCKs that
preceded it). If an EE implementation couldn't deploy with an EAR that
contained duplicate persistence unit definitions, they would have to
attempt challenging the TCK tests.
More background: the Persistence spec section
https://jakarta.ee/specifications/persistence/3.2/jakarta-persistence-spe...
<
https://jakarta.ee/specifications/persistence/3.2/jakarta-persistence-spe...
about the "Persistence Unit Scope" and how to specify a different
persistence unit in case there are duplicate persistence unit
definitions in an application. This section doesn't state a requirement
for Jakarta Persistence (EE) container implementations to allow
duplicate persistence unit definitions but it does make it possible for
applications to disambiguate application references to a duplicated
persistence unit definition.
You're right that we do, so we need to deal with that fact, but
for
the sake of context why do we do this?
The Persistence specification does have a mechanism for applications to
reference the correct persistence unit definition in case of
duplication. Perhaps a future Persistence specification could add a
requirement that duplicate persistence unit definitions not be allowed
but it would be a big breaking change. Personally, I think it could be
a good change to plan for in a future Persistence release.
Was there some important use case it allows that is otherwise
unachievable?
The use case was that some EE implementations already support duplicate
persistence unit definitions in deployments, therefore all
implementations should be able to support duplicate persistence unit
definitions so that EE applications with duplicate persistence units are
portable to all EE implementations.
I might have asked about the use case before Jakarta EE 8 and I believe
the answer was because some EE server implementations allowed duplicate
persistence unit definitions so they should be allowed for that reason.
I say might as I vaguely recall asking about this during a phone call
years ago.
My guess is this was a matter of being forgiving. Perhaps being
forgiving of the TCK, if it includes a lot of deployments like this.
I think that is a good guess but there is also the
"../lib/persistenceUnitRoot.jar#myPersistenceUnit" syntax that can be
used to reference a duplicate persistence unit that isn't in the current
subdeployment module. Also I think the TCKs contain duplicate
persistence units partly to force EE implementations to allow them.
Do we all agree this kind of deployment is an anti-pattern?
I agree.
but if we remove support for duplicate persistence unit
definitions in WildFly what would be the implication of that?
Currently we would start failing a lot of Jakarta EE TCK (Persistence)
tests that contain duplicate persistence unit definitions. Also WildFly
users would need to update their applications to remove the duplicate
persistence unit definitions as they would get "duplicate persistence
unit %s not allowed" deployment failures.
The existing JNDI-based injection is more specific in that the
"ArchivePath#" syntax is added by the app developer to specify which
persistence unit they need to use exactly. If we stopped supporting
duplicate persistence unit definitions in WildFly we would not need to
support the "ArchivePath#" syntax mentioned in
"https://jakarta.ee/specifications/persistence/3.2/jakarta-persistence-spec-3.2#a12459
<
https://jakarta.ee/specifications/persistence/3.2/jakarta-persistence-spe...;.
This brings in compatibility issues as applications will have to stop
using duplicate persistence unit definitions as we would give a
deployment failure if any were detected.
Some possible answers as to what the impact would be if WildFly
either failed to deploy applications with duplicate persistence
unit definitions or ignored some duplicate copies of the same
persistence unit definitions will be in a response to this email.
What does allowing this mean for the existing JNDI-based injection?
If we ignored some duplicate copies of the same persistence unit
definition that would break applications that actually depend on the
ignored persistence unit definition in the sense that there may be a
unique setting in the ignored persistence unit definition that was
previously used which causes different kinds of problems for the
application.
If a PU is defined in both an ear/lib and in ear/war1, but say, not
in
ear/war2, what happens?
That would cause code residing in the war2 module to fail when instead
of using the (duplicate) war2 persistence unit definition, instead the
ear/lib persistence unit is used which is missing an important
persistence unit hint that is only in the war2 persistence unit.
If we fail deployments with duplicate PU definitions, what does that
mean for the TCK? I assume if the current situation results in 10925
failures, failing the deployment would as well. We'd just be changing
how the deployment fails.
Yes that sounds correct in that we would see a lot of TCK test failures
(probably around 10925).
On the other hand if we remove the naming of the EntityManagerFactory
bean there would be zero Jakarta EE 10 TCK failures, just to mention
that possibility here.
Can ignoring some duplicate copies be restricted to this CDI use case?
Yes I think so.
IOW if there is some JNDI injection scenario that works now but would
not work if we started ignoring duplicates, can we just ignore the
duplicate for CDI injection?
We could ignore setting the EntityManagerFactory bean name (for CDI +
Persistence integration) when we detect duplicate persistence unit
definitions which is probably better than failing the deployment. Or we
could set the EntityManagerFactory bean name to a unique name when we
detect duplicate persistence unit definitions would be another way.
I don't think we want to use a more unique bean name now unless we find
that will be possible in a future EE release.
For example the PU is defined in ear/lib and in ear/war1, but not in
ear/war2. But war2 uses the PU via JNDI injection.
I think we would not name the EntityManagerFactory bean in each of the
duplicate persistence units. Unless we use a more unique name but I'm
not yet convinced that we should use a more unique name (e.g. module
archive name + persistence unit name == more unique name).
If we did that, would the TCK pass? Or is this a case of the TCK
assuming somehow vendors make deployments set up this way work. That
sounds like a TCK challenge unless there's spec language that clearly
requires it to work.
Yes as there aren't any (EE 10/11) TCK tests that inject the
EntityManagerFactory bean via the persistence unit name so no TCK
challenge is expected as of yet. Regarding the spec language, I read
the spec language last year and missed that we would get a "WELD-001414
Bean name is ambiguous..." error.
Another question that came up is should WildFly use a separate
BeanManager instance per module/submodule? I think that it is
valid for WildFly to use a global BeanManager instance as
mentioned in [5].
This would be a major change in how WF works and almost certainly
would break people somehow. Perhaps something to consider for a year
or more from now, if we think this would be better in general, but
going down this path for this particular situation seems like the last
resort.
I think there would be a lot of application compatibility issues with a
change like this as not all CDI bean references currently have to be
from the same application module. With a BeanManager per module, there
would be bean not found errors to deal with for applications.
So how can we address the failure without removing the
EntityManagerFactory bean name?
Could we use a more unique bean name that combines the containing
module name (e.g. ear/war/jar name) + the persistence unit name?
Could we contain a persistence unit hint to avoid adding the
persistence unit name to the EntityManagerFactory name?
Do you have other ideas? Or feedback on ^?
Thanks!
Scott
[1]
https://jakarta.ee/specifications/platform/11/jakarta-platform-spec-11.0#...
[2]
https://issues.redhat.com/browse/WFLY-19554
[3]
https://github.com/wildfly/wildfly/pull/19088
[4]
https://github.com/wildfly/wildfly/pull/19088/files#diff-9d21579f8a3180d3...
[5]
https://struberg.wordpress.com/2015/02/18/cdi-in-ears
_______________________________________________
wildfly-dev mailing list -- wildfly-dev(a)lists.jboss.org
To unsubscribe send an email to wildfly-dev-leave(a)lists.jboss.org
Privacy Statement:
https://www.redhat.com/en/about/privacy-policy
List Archives:
https://lists.jboss.org/archives/list/wildfly-dev@lists.jboss.org/message...
--
Brian Stansberry
Architect, JBoss EAP
WildFly Project Lead
He/Him/His
_______________________________________________
wildfly-dev mailing list --wildfly-dev(a)lists.jboss.org
To unsubscribe send an email towildfly-dev-leave(a)lists.jboss.org
Privacy
Statement:https://www.redhat.com/en/about/privacy-policy
List
Archives:https://lists.jboss.org/archives/list/wildfly-dev@lists.jboss.or...