TOMEE-4650 - Guard undeploy against a closed EMF and add JPA 3.2 CDI qualifier beans#2847
TOMEE-4650 - Guard undeploy against a closed EMF and add JPA 3.2 CDI qualifier beans#2847jungm wants to merge 1 commit into
Conversation
…qualifier beans Two independent problems, both reproducing on Plume (EclipseLink) and the webprofile distribution (OpenJPA), so neither is a provider defect. 1. When an application closes a container-managed EntityManagerFactory itself, TomEE's undeploy path closed it again, and Assembler.destroyApplication then failed with "Attempting to execute an operation on a closed EntityManagerFactory". ReloadableEntityManagerFactory.close() now checks isOpen() before delegating. 2. TomEE did not register the CDI beans required by the Jakarta Persistence 3.2 / Jakarta EE 11 CDI integration for persistence.xml-declared units, so injecting a qualified EntityManagerFactory / EntityManager / PersistenceUnitUtil failed with UnsatisfiedResolutionException. A new JpaCDIExtension registers, per persistence unit, an @ApplicationScoped EntityManagerFactory (bean name = PU name), an EntityManager in the <scope> element's scope (default TransactionScoped), and @dependent CriteriaBuilder, PersistenceUnitUtil, Cache, SchemaManager and Metamodel beans, all carrying the <qualifier> elements or @default when none is declared. Supporting this, <qualifier>/<scope> are added to the persistence.xml JAXB model (PersistenceUnit), to PersistenceUnitInfo, and copied through AppInfoBuilder, which also honours the jakarta.persistence.qualifiers / jakarta.persistence.scope override properties. Bean-registration contract verified against the Jakarta EE 11 Platform spec (CDI-JPA) and the Persistence 3.2 schema rather than from memory. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
Could you split this? There are two unrelated changes here and they're in very different states. Part 1 — the Part 2 — Blocking:
Also:
Question rather than a finding: Low-priority, only reachable via the JPA JMX operations: the |
Fixes TOMEE-4650. Two independent problems, both reproducing on Plume (EclipseLink) and the webprofile distribution (OpenJPA) — so neither is a persistence-provider defect.
1. Undeploy closes an already-closed EntityManagerFactory
When a test (or application) closes a container-managed
EntityManagerFactoryitself, TomEE's undeploy path calledclose()on it again, andAssembler.destroyApplicationthen failed with "Attempting to execute an operation on a closed EntityManagerFactory". The test method passed; only the undeploy step errored.ReloadableEntityManagerFactory.close()now checksisOpen()before delegating to the underlying EMF.2. Missing Jakarta Persistence 3.2 CDI qualifier beans
TomEE did not register the CDI beans that the Jakarta EE 11 / Persistence 3.2 CDI integration requires for
persistence.xml-declared units. Injecting a qualifiedEntityManagerFactory,EntityManager, orPersistenceUnitUtil(e.g.@Inject @CtsEm2Qualifier) failed at deploy time withUnsatisfiedResolutionException.A new
JpaCDIExtensionregisters, for each persistence unit:EntityManagerFactory—@ApplicationScoped, bean name = persistence-unit nameEntityManager— in the scope given by<scope>, defaulting tojakarta.transaction.TransactionScopedCriteriaBuilder,PersistenceUnitUtil,Cache,SchemaManager,Metamodel—@Dependent, each obtained from the matching getter of the EMFAll of them carry the qualifiers declared by the
<qualifier>elements, or@Defaultwhen none is declared. The bean-registration contract (scopes, qualifiers, bean name) was checked against the Jakarta EE 11 Platform spec (CDI-JPA) and the Persistence 3.2 schema rather than from memory.Supporting plumbing:
<qualifier>/<scope>added to thepersistence.xmlJAXB model (PersistenceUnit) in the XSD-mandated position. This model is hand-maintained, not generated (the xjc profile does not cover persistence schemas), and TomEE does not validatepersistence.xmlagainst a bundled XSD, so no schema files needed updating.PersistenceUnitInfoandAppInfoBuilder, which also honours thejakarta.persistence.qualifiers/jakarta.persistence.scopeoverride properties per the spec.OptimizedLoaderService, alongside the analogousConcurrencyCDIExtensionit is modeled on.Tests
ReloadableEntityManagerFactoryCloseTest— verifies a secondclose()is a no-op. Confirmed it fails against the unpatched code (2 close calls instead of 1).JpaCDIExtensionTest— verifies qualified and@DefaultEMF/PersistenceUnitUtilinjection across two persistence units. Confirmed it fails against the unpatched code with the exactUnsatisfiedResolutionExceptionfrom the issue.Notes for reviewers
entityManagerFactoryCloseExceptions/ClientP{m,u}servletTest,ee.cdi.ServletEMLookupTest) live in the separateapache/tomee-tckharness repo; their exclusion lines still need removing there once this merges. That change is not in this PR.SchemaManager/Metamodel/CriteriaBuilder/Cachebeans are registered per spec but onlyEntityManagerFactoryandPersistenceUnitUtilare exercised in the unit tests — the others eagerly trigger OpenJPA entity enhancement, which the unenhanced test setup in this module cannot satisfy. The full validation is a TCK run.🤖 Generated with Claude Code