You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2018/12/06 17:33:24 UTC

[02/24] tomee git commit: TOMEE-2295 Improvements for JPA/CMP mapping

TOMEE-2295 Improvements for JPA/CMP mapping


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ddbae44e
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ddbae44e
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ddbae44e

Branch: refs/heads/master
Commit: ddbae44e280cb9e8f0e10ea7754b5eed69733cb4
Parents: 9c585b0
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Nov 28 13:53:40 2018 +0000
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Nov 28 13:53:40 2018 +0000

----------------------------------------------------------------------
 .../apache/openejb/config/CmpJpaConversion.java | 110 +++++++++++++------
 .../openejb/core/LegacyInterfaceTest.java       |  40 ++-----
 2 files changed, 84 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/ddbae44e/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java b/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
index 7f0e3f1..194bbd9 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
@@ -20,20 +20,7 @@ package org.apache.openejb.config;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.core.cmp.CmpUtil;
 import org.apache.openejb.core.cmp.jpa.JpaCmpEngine;
-import org.apache.openejb.jee.CmpField;
-import org.apache.openejb.jee.CmpVersion;
-import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.EjbRelation;
-import org.apache.openejb.jee.EjbRelationshipRole;
-import org.apache.openejb.jee.EnterpriseBean;
-import org.apache.openejb.jee.EntityBean;
-import org.apache.openejb.jee.Multiplicity;
-import org.apache.openejb.jee.PersistenceContextRef;
-import org.apache.openejb.jee.PersistenceType;
-import org.apache.openejb.jee.Query;
-import org.apache.openejb.jee.QueryMethod;
-import org.apache.openejb.jee.RelationshipRoleSource;
-import org.apache.openejb.jee.Relationships;
+import org.apache.openejb.jee.*;
 import org.apache.openejb.jee.jpa.AttributeOverride;
 import org.apache.openejb.jee.jpa.Attributes;
 import org.apache.openejb.jee.jpa.Basic;
@@ -58,6 +45,7 @@ import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
 import org.apache.openejb.jee.jpa.unit.TransactionType;
 import org.apache.openejb.jee.oejb3.EjbDeployment;
 import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.loader.IO;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -67,6 +55,7 @@ import javax.ejb.EJBLocalObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.net.URL;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -99,15 +88,38 @@ public class CmpJpaConversion implements DynamicDeployer {
         "serialVersionUID"
     )));
 
+    public static EntityMappings readEntityMappings(final String location) {
+
+        // first try the classpath
+        EntityMappings entitymappings = null;
+
+        try {
+            final URL cpUrl = Thread.currentThread().getContextClassLoader().getResource(location);
+            entitymappings = (EntityMappings) JaxbJavaee.unmarshal(EntityMappings.class, IO.read(cpUrl));
+        } catch (Exception e) {
+            // ignore
+        }
+
+        if (entitymappings == null) {
+            // then try reading as a URL
+            try {
+                final URL url = new URL(location);
+                entitymappings = (EntityMappings) JaxbJavaee.unmarshal(EntityMappings.class, IO.read(url));
+            } catch (Exception e) {
+                logger.error("Unable to read entity mappings from " + location, e);
+            }
+        }
+
+        return entitymappings;
+    }
+
     public AppModule deploy(final AppModule appModule) throws OpenEJBException {
 
         if (!hasCmpEntities(appModule)) {
             return appModule;
         }
 
-        // todo scan existing persistence module for all entity mappings and don't generate mappings for them
-
-        // create mappings if no mappings currently exist 
+        // create mappings if no mappings currently exist
         EntityMappings cmpMappings = appModule.getCmpMappings();
         if (cmpMappings == null) {
             cmpMappings = new EntityMappings();
@@ -115,6 +127,23 @@ public class CmpJpaConversion implements DynamicDeployer {
             appModule.setCmpMappings(cmpMappings);
         }
 
+        // todo scan existing persistence module for all entity mappings and don't generate mappings for them
+
+        final Set<String> definedMappedClasses = new HashSet<>();
+
+        // check for an existing "cmp" persistence unit, and look at existing mappings
+        final PersistenceUnit cmpPersistenceUnit = findCmpPersistenceUnit(appModule);
+        if (cmpPersistenceUnit != null) {
+            if (cmpPersistenceUnit.getMappingFile() != null || cmpPersistenceUnit.getMappingFile().size() > 0) {
+                for (final String mappingFile : cmpPersistenceUnit.getMappingFile()) {
+                    final EntityMappings entityMappings = readEntityMappings(mappingFile);
+                    if (entityMappings != null) {
+                        definedMappedClasses.addAll(entityMappings.getEntityMap().keySet());
+                    }
+                }
+            }
+        }
+
         // we process this one jar-file at a time...each contributing to the 
         // app mapping data 
         for (final EjbModule ejbModule : appModule.getEjbModules()) {
@@ -123,7 +152,7 @@ public class CmpJpaConversion implements DynamicDeployer {
             // scan for CMP entity beans and merge the data into the collective set 
             for (final EnterpriseBean enterpriseBean : ejbJar.getEnterpriseBeans()) {
                 if (isCmpEntity(enterpriseBean)) {
-                    processEntityBean(ejbModule, cmpMappings, (EntityBean) enterpriseBean);
+                    processEntityBean(ejbModule, definedMappedClasses, cmpMappings, (EntityBean) enterpriseBean);
                 }
             }
 
@@ -152,7 +181,6 @@ public class CmpJpaConversion implements DynamicDeployer {
             for (final MappedSuperclass mapping : userMappings.getMappedSuperclass()) {
                 logger.warning("openejb-cmp-orm.xml mapping ignored: module=" + ejbModule.getModuleId() + ":  <mapped-superclass class=\"" + mapping.getClazz() + "\">");
             }
-
         }
 
         if (!cmpMappings.getEntity().isEmpty()) {
@@ -160,7 +188,9 @@ public class CmpJpaConversion implements DynamicDeployer {
 
             persistenceUnit.getMappingFile().add("META-INF/openejb-cmp-generated-orm.xml");
             for (final Entity entity : cmpMappings.getEntity()) {
-                persistenceUnit.getClazz().add(entity.getClazz());
+                if (! persistenceUnit.getClazz().contains(entity.getClazz())) {
+                    persistenceUnit.getClazz().add(entity.getClazz());
+                }
             }
         }
 
@@ -176,17 +206,7 @@ public class CmpJpaConversion implements DynamicDeployer {
 
     private PersistenceUnit getCmpPersistenceUnit(final AppModule appModule) {
         // search for the cmp persistence unit
-        PersistenceUnit persistenceUnit = null;
-        for (final PersistenceModule persistenceModule : appModule.getPersistenceModules()) {
-            final Persistence persistence = persistenceModule.getPersistence();
-            for (final PersistenceUnit unit : persistence.getPersistenceUnit()) {
-                if (CMP_PERSISTENCE_UNIT_NAME.equals(unit.getName())) {
-                    persistenceUnit = unit;
-                    break;
-                }
-
-            }
-        }
+        PersistenceUnit persistenceUnit = findCmpPersistenceUnit(appModule);
         // if not found create one
         if (persistenceUnit == null) {
             persistenceUnit = new PersistenceUnit();
@@ -215,6 +235,21 @@ public class CmpJpaConversion implements DynamicDeployer {
         return persistenceUnit;
     }
 
+    private PersistenceUnit findCmpPersistenceUnit(final AppModule appModule) {
+        PersistenceUnit persistenceUnit = null;
+        for (final PersistenceModule persistenceModule : appModule.getPersistenceModules()) {
+            final Persistence persistence = persistenceModule.getPersistence();
+            for (final PersistenceUnit unit : persistence.getPersistenceUnit()) {
+                if (CMP_PERSISTENCE_UNIT_NAME.equals(unit.getName())) {
+                    persistenceUnit = unit;
+                    break;
+                }
+
+            }
+        }
+        return persistenceUnit;
+    }
+
     private String getPersistenceModuleId(final AppModule appModule) {
         if (appModule.getModuleId() != null) {
             return appModule.getModuleId();
@@ -437,12 +472,14 @@ public class CmpJpaConversion implements DynamicDeployer {
     /**
      * Generate the CMP mapping data for an individual
      * EntityBean.
-     *
-     * @param ejbModule      The module containing the bean.
+     *  @param ejbModule      The module containing the bean.
+     * @param ignoreClasses
      * @param entityMappings The accumulated set of entity mappings.
      * @param bean           The been we're generating the mapping for.
      */
-    private void processEntityBean(final EjbModule ejbModule, final EntityMappings entityMappings, final EntityBean bean) {
+    private void processEntityBean(final EjbModule ejbModule, final Collection<String> ignoreClasses,
+                                   final EntityMappings entityMappings, final EntityBean bean) {
+
         // try to add a new persistence-context-ref for cmp
         if (!addPersistenceContextRef(bean)) {
             // Bean already has a persistence-context-ref for cmp
@@ -478,6 +515,11 @@ public class CmpJpaConversion implements DynamicDeployer {
             }
         }
 
+        // Check that this mapping hasn't already been defined in another mapping file on the persistence unit
+        if (ignoreClasses.contains(jpaEntityClassName)) {
+            return;
+        }
+
         // Look for an existing mapping using the openejb generated subclass name
         Entity entity = removeEntity(userMappings, jpaEntityClassName);
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/ddbae44e/container/openejb-core/src/test/java/org/apache/openejb/core/LegacyInterfaceTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/LegacyInterfaceTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/LegacyInterfaceTest.java
index 0b4b73f..0e1f2d7 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/core/LegacyInterfaceTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/LegacyInterfaceTest.java
@@ -253,43 +253,16 @@ public class LegacyInterfaceTest extends TestCase {
             throw new Exception("Failed to create test directory: " + f);
         }
 
-        final EntityMappings entityMappings = new EntityMappings();
-
-        final Entity entity = new Entity();
-        entity.setClazz("openejb.org.apache.openejb.core.MyCmpBean");
-        entity.setName("MyCmpBean");
-        entity.setDescription("MyCmpBean");
-        entity.setAttributes(new Attributes());
-
-        final NamedQuery namedQuery = new NamedQuery();
-        namedQuery.setQuery("SELECT OBJECT(DL) FROM License DL");
-        entity.getNamedQuery().add(namedQuery);
-
-        final Id id = new Id();
-        id.setName("id");
-        entity.getAttributes().getId().add(id);
-
-        final Basic basic = new Basic();
-        basic.setName("name");
-        final Column column = new Column();
-        column.setName("wNAME");
-        column.setLength(300);
-        basic.setColumn(column);
-        entity.getAttributes().getBasic().add(basic);
-
-        entityMappings.getEntity().add(entity);
-
         final AppModule module = new AppModule(this.getClass().getClassLoader(), f.getAbsolutePath());
         final EjbModule ejbModule = new EjbModule(ejbJar);
 
-
         Persistence persistence = new Persistence();
         PersistenceUnit pu = persistence.addPersistenceUnit("cmp");
         pu.setTransactionType(TransactionType.JTA);
         pu.setJtaDataSource("fake");
         pu.setNonJtaDataSource("fake");
         pu.getMappingFile().add("test-orm.xml");
-        pu.addClass("openejb.org.apache.openejb.core.MyCmpBean");
+        pu.getClazz().add("openejb.org.apache.openejb.core.MyCmpBean");
         module.addPersistenceModule(new PersistenceModule("pu", persistence));
 
         module.getEjbModules().add(ejbModule);
@@ -297,12 +270,15 @@ public class LegacyInterfaceTest extends TestCase {
         assertNull(module.getCmpMappings());
         assembler.createApplication(config.configureApplication(module));
         assertNotNull(module.getCmpMappings());
+
+        // no mapping should be automatically generated
+        assertTrue(module.getCmpMappings().getEntityMap().isEmpty());
+
+        // pu should not be modified, no duplicate classes
         assertEquals(1, pu.getClazz().size());
         assertEquals("openejb.org.apache.openejb.core.MyCmpBean", pu.getClazz().get(0));
-        final List<Basic> basicList = module.getCmpMappings().getEntityMap().get("openejb.org.apache.openejb.core.MyCmpBean").getAttributes().getBasic();
-        assertEquals(1, basicList.size());
-        assertEquals(300, basicList.get(0).getColumn().getLength().intValue());
-        assertEquals("wNAME", basicList.get(0).getColumn().getName());
+        assertEquals(1, pu.getMappingFile().size());
+        assertEquals("test-orm.xml", pu.getMappingFile().get(0));
     }
 
     @LocalHome(MyLocalHome.class)