From 398b8ba84bef8107b68ca1d1286fe456718b3a15 Mon Sep 17 00:00:00 2001 From: Laird Nelson Date: Wed, 2 Oct 2024 14:14:22 -0700 Subject: [PATCH] Adds test in jpa-cdi to prove that application- and container-managed EntityManagers can co-exist (#9145) Signed-off-by: Laird Nelson --- ...licationAndContainerManagedInjections.java | 141 ++++++++++++++++++ .../test/resources/META-INF/persistence.xml | 7 +- 2 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 integrations/cdi/jpa-cdi/src/test/java/io/helidon/integrations/cdi/jpa/TestApplicationAndContainerManagedInjections.java diff --git a/integrations/cdi/jpa-cdi/src/test/java/io/helidon/integrations/cdi/jpa/TestApplicationAndContainerManagedInjections.java b/integrations/cdi/jpa-cdi/src/test/java/io/helidon/integrations/cdi/jpa/TestApplicationAndContainerManagedInjections.java new file mode 100644 index 00000000000..163e69448d9 --- /dev/null +++ b/integrations/cdi/jpa-cdi/src/test/java/io/helidon/integrations/cdi/jpa/TestApplicationAndContainerManagedInjections.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.integrations.cdi.jpa; + +import java.util.Objects; + +import jakarta.annotation.sql.DataSourceDefinition; +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.se.SeContainer; +import jakarta.enterprise.inject.se.SeContainerInitializer; +import jakarta.enterprise.inject.Disposes; +import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceContext; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static jakarta.persistence.Persistence.createEntityManagerFactory; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +class TestApplicationAndContainerManagedInjections { + + private SeContainer sec; + + private TestApplicationAndContainerManagedInjections() { + super(); + } + + @BeforeEach + @SuppressWarnings("unchecked") + final void initializeCdiContainer() { + System.setProperty(JpaExtension.class.getName() + ".enabled", "false"); + System.setProperty(PersistenceExtension.class.getName() + ".enabled", "true"); + Class cdiSeJtaPlatformClass; + try { + // Load it dynamically because Hibernate won't be on the classpath when we're testing with Eclipselink + cdiSeJtaPlatformClass = + Class.forName("io.helidon.integrations.cdi.hibernate.CDISEJtaPlatform", + false, + Thread.currentThread().getContextClassLoader()); + } catch (ClassNotFoundException e) { + cdiSeJtaPlatformClass = null; + } + SeContainerInitializer i = SeContainerInitializer.newInstance() + .disableDiscovery() + .addExtensions(PersistenceExtension.class, + com.arjuna.ats.jta.cdi.TransactionExtension.class, + io.helidon.integrations.datasource.hikaricp.cdi.HikariCPBackedDataSourceExtension.class) + .addBeanClasses(Frobnicator.class); + if (cdiSeJtaPlatformClass != null) { + i = i.addBeanClasses(cdiSeJtaPlatformClass); + } + this.sec = i.initialize(); + } + + @AfterEach + final void closeCdiContainer() { + if (this.sec != null) { + this.sec.close(); + } + System.setProperty(PersistenceExtension.class.getName() + ".enabled", "false"); + System.setProperty(JpaExtension.class.getName() + ".enabled", "true"); + } + + @Test + final void testApplicationAndContainerManagedInjections() { + Instance fi = sec.select(Frobnicator.class); + Frobnicator f = fi.get(); + assertThat(f.containerManagedEm.isOpen(), is(true)); + assertThat(f.containerManagedEm, instanceOf(JtaEntityManager.class)); + assertThat(f.applicationManagedEm.isOpen(), is(true)); + fi.destroy(f); + } + + @DataSourceDefinition( + name = "test", + className = "org.h2.jdbcx.JdbcDataSource", + url = "jdbc:h2:mem:TestApplicationAndContainerManagedInjections", + serverName = "", + properties = { + "user=sa" + } + ) + @Dependent + private static class Frobnicator { + + @PersistenceContext(unitName = "test") + private EntityManager containerManagedEm; + + private final EntityManager applicationManagedEm; + + @Inject + Frobnicator(EntityManager applicationManagedEm) { + super(); + this.applicationManagedEm = Objects.requireNonNull(applicationManagedEm); + } + + @Produces + @Singleton + static EntityManagerFactory produceApplicationManagedEntityManagerFactory() { + return createEntityManagerFactory("test-resource-local"); + } + + static void disposeApplicationManagedEntityManagerFactory(@Disposes EntityManagerFactory applicationManagedEmf) { + applicationManagedEmf.close(); + } + + @Produces + @Dependent + static EntityManager produceApplicationManagedEntityManager(EntityManagerFactory applicationManagedEmf) { + return applicationManagedEmf.createEntityManager(); + } + + static void disposeApplicationManagedEntityManager(@Disposes EntityManager applicationManagedEm) { + applicationManagedEm.close(); + } + + } + +} diff --git a/integrations/cdi/jpa-cdi/src/test/resources/META-INF/persistence.xml b/integrations/cdi/jpa-cdi/src/test/resources/META-INF/persistence.xml index e1698885042..f81c39f1381 100644 --- a/integrations/cdi/jpa-cdi/src/test/resources/META-INF/persistence.xml +++ b/integrations/cdi/jpa-cdi/src/test/resources/META-INF/persistence.xml @@ -1,7 +1,7 @@