You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2008/01/05 22:44:18 UTC

svn commit: r609224 - in /cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa: bridge/DataMapConverter.java conf/EntityMapDefaultsProcessor.java conf/EntityMapLoader.java map/JpaEntity.java map/JpaEntityMap.java

Author: aadamchik
Date: Sat Jan  5 13:44:16 2008
New Revision: 609224

URL: http://svn.apache.org/viewvc?rev=609224&view=rev
Log:
CAY-953 JPA: Single Table inheritance
(basic mapping bridging...)

Modified:
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapLoader.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java?rev=609224&r1=609223&r2=609224&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java Sat Jan  5 13:44:16 2008
@@ -23,6 +23,8 @@
 import java.lang.reflect.Field;
 import java.util.Iterator;
 
+import javax.persistence.InheritanceType;
+
 import org.apache.cayenne.jpa.JpaProviderException;
 import org.apache.cayenne.jpa.conf.EntityMapLoaderContext;
 import org.apache.cayenne.jpa.map.AccessType;
@@ -439,7 +441,7 @@
             if (managedClass instanceof JpaEntity) {
                 JpaEntity entity = (JpaEntity) managedClass;
 
-                if (column.getTable().equals(entity.getTable().getName())) {
+                if (column.getTable().equals(entity.lookupTable().getName())) {
                     return column.getName();
                 }
 
@@ -679,6 +681,12 @@
         Object createObject(ProjectPath path) {
             JpaEntity jpaEntity = (JpaEntity) path.getObject();
             ObjEntity cayenneEntity = new ObjEntity(jpaEntity.getName());
+
+            if (jpaEntity.getInheritance() == null
+                    && jpaEntity.lookupInheritanceStrategy() == InheritanceType.SINGLE_TABLE) {
+                cayenneEntity.setSuperEntityName(jpaEntity.getSuperEntity().getName());
+            }
+
             cayenneEntity.setClassName(jpaEntity.getClassName());
             initCallbacks(jpaEntity, cayenneEntity);
 

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java?rev=609224&r1=609223&r2=609224&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java Sat Jan  5 13:44:16 2008
@@ -25,6 +25,7 @@
 import java.util.Date;
 
 import javax.persistence.EnumType;
+import javax.persistence.InheritanceType;
 import javax.persistence.TemporalType;
 
 import org.apache.cayenne.jpa.JpaProviderException;
@@ -116,28 +117,6 @@
                 return false;
             }
 
-            if (abstractEntity instanceof JpaEntity) {
-                JpaEntity entity = (JpaEntity) abstractEntity;
-                if (entity.getName() == null) {
-                    // use unqualified class name
-                    String fqName = abstractEntity.getClassName();
-                    int split = fqName.lastIndexOf('.');
-                    entity.setName(split > 0 ? fqName.substring(split + 1) : fqName);
-                }
-
-                // * default table (see @Table annotation defaults, JPA spec 9.1.1)
-                if (entity.getTable() == null) {
-                    JpaTable table = new JpaTable(AnnotationPrototypes.getTable());
-
-                    // unclear whether we need to apply any other name transformations ...
-                    // or even if we need to uppercase the name. Per default examples
-                    // looks
-                    // like we need. table.setName(entity.getName().toUpperCase());
-                    table.setName(entity.getName());
-                    entity.setTable(table);
-                }
-            }
-
             if (abstractEntity.getAttributes() == null) {
                 abstractEntity.setAttributes(new JpaAttributes());
             }
@@ -311,7 +290,7 @@
 
                 // parent can be a mapped superclass
                 if (entity != null) {
-                    column.setTable(entity.getTable().getName());
+                    column.setTable(entity.lookupTable().getName());
                 }
             }
 
@@ -361,6 +340,47 @@
     }
 
     final class EntityVisitor extends AbstractEntityVisitor {
+
+        @Override
+        public boolean onStartNode(ProjectPath path) {
+            if (super.onStartNode(path)) {
+
+                JpaEntity entity = (JpaEntity) path.getObject();
+
+                if (entity.getInheritance() != null
+                        && entity.getInheritance().getStrategy() == null) {
+                    entity.getInheritance().setStrategy(InheritanceType.SINGLE_TABLE);
+                }
+
+                if (entity.getName() == null) {
+                    // use unqualified class name
+                    String fqName = entity.getClassName();
+                    int split = fqName.lastIndexOf('.');
+                    entity.setName(split > 0 ? fqName.substring(split + 1) : fqName);
+                }
+
+                if (entity.getInheritance() == null
+                        && entity.lookupInheritanceStrategy() == InheritanceType.SINGLE_TABLE) {
+                    // no dedicated table for the single_table inheritance subclass
+                }
+                // default table (see @Table annotation defaults, JPA spec 9.1.1)
+                else if (entity.getTable() == null) {
+                    JpaTable table = new JpaTable(AnnotationPrototypes.getTable());
+
+                    // unclear whether we need to apply any other name transformations
+                    // ...
+                    // or even if we need to uppercase the name. Per default examples
+                    // looks
+                    // like we need. table.setName(entity.getName().toUpperCase());
+                    table.setName(entity.getName());
+                    entity.setTable(table);
+                }
+
+                return true;
+            }
+
+            return false;
+        }
 
         @Override
         public void onFinishNode(ProjectPath path) {

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapLoader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapLoader.java?rev=609224&r1=609223&r2=609224&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapLoader.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapLoader.java Sat Jan  5 13:44:16 2008
@@ -34,13 +34,14 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
-import javax.persistence.spi.PersistenceUnitInfo;
 import javax.persistence.Embeddable;
 import javax.persistence.Entity;
 import javax.persistence.MappedSuperclass;
+import javax.persistence.spi.PersistenceUnitInfo;
 
 import org.apache.cayenne.jpa.JpaProviderException;
 import org.apache.cayenne.jpa.map.JpaClassDescriptor;
+import org.apache.cayenne.jpa.map.JpaEntity;
 import org.apache.cayenne.jpa.map.JpaEntityMap;
 
 /**
@@ -111,6 +112,7 @@
         try {
             loadFromAnnotations(persistenceUnit);
             updateFromXML(persistenceUnit);
+            updateInheritanceHierarchy();
             updateFromDefaults();
         }
         catch (JpaProviderException e) {
@@ -118,6 +120,30 @@
         }
         catch (Exception e) {
             throw new JpaProviderException("Error loading ORM descriptors", e);
+        }
+    }
+
+    protected void updateInheritanceHierarchy() {
+
+        JpaEntityMap map = getEntityMap();
+
+        for (JpaEntity entity : map.getEntities()) {
+
+            Class<?> superclass = entity
+                    .getClassDescriptor()
+                    .getManagedClass()
+                    .getSuperclass();
+
+            while (superclass != null && !superclass.getName().equals("java.lang.Object")) {
+
+                JpaEntity superEntity = map.getEntity(superclass.getName());
+                if (superEntity != null) {
+                    entity.setSuperEntity(superEntity);
+                    break;
+                }
+
+                superclass = superclass.getSuperclass();
+            }
         }
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java?rev=609224&r1=609223&r2=609224&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java Sat Jan  5 13:44:16 2008
@@ -22,6 +22,8 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
+import javax.persistence.InheritanceType;
+
 import org.apache.cayenne.util.TreeNodeChild;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
@@ -43,6 +45,7 @@
     protected JpaSqlResultSetMapping sqlResultSetMapping;
     protected Collection<JpaAttributeOverride> attributeOverrides;
     protected Collection<JpaAssociationOverride> associationOverrides;
+    protected JpaEntity superEntity;
 
     // TODO: andrus, 7/25/2006 - according to the notes in the JPA spec FR, these
     // annotations can be specified on a mapped superclass as well as entity. Check the
@@ -220,11 +223,47 @@
         this.discriminatorValue = discriminatorValue;
     }
 
+    /**
+     * Returns a child JpaInheritance object that is only set on a root of inheritance
+     * hierarchy.
+     */
     @TreeNodeChild
     public JpaInheritance getInheritance() {
         return inheritance;
     }
 
+    /**
+     * Returns inheritance type for this entity hierarchy. If the entity has no
+     * inheritance settings, returns null.
+     */
+    public InheritanceType lookupInheritanceStrategy() {
+
+        if (inheritance != null) {
+            return inheritance.getStrategy();
+        }
+
+        if (superEntity != null) {
+            return superEntity.lookupInheritanceStrategy();
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a table for this entity hierarchy.
+     */
+    public JpaTable lookupTable() {
+        if (table != null) {
+            return table;
+        }
+        
+        if(superEntity != null) {
+            return superEntity.lookupTable();
+        }
+        
+        return null;
+    }
+
     public void setInheritance(JpaInheritance inheritance) {
         this.inheritance = inheritance;
     }
@@ -323,21 +362,29 @@
         }
         return secondaryTables;
     }
-    
+
     public JpaSecondaryTable getSecondaryTable(String name) {
         if (secondaryTables != null) {
-            for(JpaSecondaryTable table : secondaryTables) {
-                if(name.equals(table.getName())) {
+            for (JpaSecondaryTable table : secondaryTables) {
+                if (name.equals(table.getName())) {
                     return table;
                 }
             }
         }
-        
+
         return null;
     }
 
     @Override
     public String toString() {
         return "JpaEntity:" + name;
+    }
+
+    public JpaEntity getSuperEntity() {
+        return superEntity;
+    }
+
+    public void setSuperEntity(JpaEntity superEntity) {
+        this.superEntity = superEntity;
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java?rev=609224&r1=609223&r2=609224&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java Sat Jan  5 13:44:16 2008
@@ -122,6 +122,22 @@
         encoder.print("</entity-mappings>");
     }
 
+    public JpaEntity getEntity(String className) {
+        if (className == null) {
+            throw new IllegalArgumentException("Null class name");
+        }
+
+        if (entities != null) {
+            for (JpaEntity object : entities) {
+                if (className.equals(object.getClassName())) {
+                    return object;
+                }
+            }
+        }
+
+        return null;
+    }
+
     /**
      * Returns an existing managed class, or null if no match is found.
      */