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 2006/05/03 04:12:47 UTC

svn commit: r399108 - in /incubator/cayenne/jpa/trunk/cayenne-jpa/src: main/java/org/apache/cayenne/jpa/bridge/ main/java/org/apache/cayenne/jpa/conf/ test/java/org/apache/cayenne/jpa/bridge/ test/java/org/apache/cayenne/jpa/entity/cayenne/

Author: aadamchik
Date: Tue May  2 19:12:44 2006
New Revision: 399108

URL: http://svn.apache.org/viewcvs?rev=399108&view=rev
Log:
(unfinished) join conversion support

Modified:
    incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
    incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java
    incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/bridge/DataMapMappingAssertion.java
    incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneEntity1.java
    incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneTargetEntity2.java

Modified: incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java?rev=399108&r1=399107&r2=399108&view=diff
==============================================================================
--- incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java (original)
+++ incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java Tue May  2 19:12:44 2006
@@ -31,6 +31,7 @@
 import org.apache.cayenne.jpa.map.JpaEntity;
 import org.apache.cayenne.jpa.map.JpaEntityMap;
 import org.apache.cayenne.jpa.map.JpaId;
+import org.apache.cayenne.jpa.map.JpaJoinColumn;
 import org.apache.cayenne.jpa.map.JpaManyToMany;
 import org.apache.cayenne.jpa.map.JpaManyToOne;
 import org.apache.cayenne.jpa.map.JpaNamedQuery;
@@ -46,6 +47,7 @@
 import org.objectstyle.cayenne.map.DataMap;
 import org.objectstyle.cayenne.map.DbAttribute;
 import org.objectstyle.cayenne.map.DbEntity;
+import org.objectstyle.cayenne.map.DbJoin;
 import org.objectstyle.cayenne.map.DbRelationship;
 import org.objectstyle.cayenne.map.ObjAttribute;
 import org.objectstyle.cayenne.map.ObjEntity;
@@ -289,6 +291,75 @@
         }
     }
 
+    class JpaJoinColumnVisitor extends BaseTreeVisitor {
+
+        @Override
+        public boolean onStartNode(ProjectPath path) {
+
+            JpaJoinColumn jpaJoin = (JpaJoinColumn) path.getObject();
+            JpaRelationship jpaRelationship = (JpaRelationship) path.getObjectParent();
+            JpaEntity targetEntity = context.getEntityMap().entityForClass(
+                    jpaRelationship.getTargetEntityName());
+            JpaId jpaTargetId = targetEntity.idForName(jpaJoin.getReferencedColumnName());
+
+            ObjRelationship objRelationship = (ObjRelationship) targetPath.getObject();
+            DataMap dataMap = objRelationship.getSourceEntity().getDataMap();
+
+            // add FK
+            DbAttribute src = new DbAttribute(jpaJoin.getName());
+
+            // TODO: andrus, 5/2/2006 - infer this from Jpa relationship
+            src.setMandatory(false);
+            src.setMaxLength(jpaTargetId.getColumn().getLength());
+
+            // per JPA spec only date types are mapped explicitly...
+            int type;
+            if (jpaTargetId.getTemporal() != null) {
+                if (TemporalType.TIMESTAMP == jpaTargetId.getTemporal()) {
+                    type = Types.TIMESTAMP;
+                }
+                else if (TemporalType.DATE == jpaTargetId.getTemporal()) {
+                    type = Types.DATE;
+                }
+                else {
+                    type = Types.TIME;
+                }
+            }
+            else {
+                JpaPropertyDescriptor property = context.getLoadedDescriptor(
+                        jpaRelationship.getTargetEntityName()).getProperty(
+                        jpaTargetId.getName());
+                type = TypesMapping.getSqlTypeByJava(property.getType());
+            }
+
+            src.setType(type);
+
+            DbEntity srcEntity = dataMap.getDbEntity(jpaJoin.getTable());
+            srcEntity.addAttribute(src);
+
+            // add join
+            DbRelationship dbRelationship = (DbRelationship) objRelationship
+                    .getDbRelationships()
+                    .get(0);
+
+            DbRelationship reverseRelationship = dbRelationship.getReverseRelationship();
+            if (reverseRelationship == null) {
+                reverseRelationship = dbRelationship.createReverseRelationship();
+            }
+
+            DbJoin join = new DbJoin(dbRelationship, src.getName(), jpaTargetId
+                    .getColumn()
+                    .getName());
+            DbJoin reverseJoin = join.createReverseJoin();
+            reverseJoin.setRelationship(reverseRelationship);
+
+            dbRelationship.addJoin(join);
+            reverseRelationship.addJoin(reverseJoin);
+
+            return false;
+        }
+    }
+
     class JpaEntityVisitor extends NestedVisitor {
 
         JpaEntityVisitor() {
@@ -329,10 +400,15 @@
         }
     }
 
-    class JpaRelationshipVisitor extends BaseTreeVisitor {
+    class JpaRelationshipVisitor extends NestedVisitor {
+
+        JpaRelationshipVisitor() {
+            addChildVisitor(JpaJoinColumn.class, new JpaJoinColumnVisitor());
+        }
 
         @Override
-        public boolean onStartNode(ProjectPath path) {
+        Object createObject(ProjectPath path) {
+
             JpaRelationship relationship = (JpaRelationship) path.getObject();
 
             ObjEntity cayenneSrcEntity = (ObjEntity) targetPath.getObject();
@@ -348,11 +424,13 @@
             if (jpaTargetEntity == null) {
                 recordConflict(path, "Unknown target entity '"
                         + relationship.getTargetEntityName());
-                return false;
+                return null;
             }
 
             cayenneRelationship.setTargetEntityName(jpaTargetEntity.getName());
 
+            // TODO: db relationship should probably be created when the first join is
+            // created...
             DbEntity cayenneSrcDbEntity = cayenneSrcEntity.getDbEntity();
 
             DbEntity cayenneTargetDbEntity = cayenneSrcEntity.getDataMap().getDbEntity(
@@ -366,10 +444,11 @@
                     .getName());
             dbRelationship.setTargetEntity(cayenneTargetDbEntity);
             dbRelationship.setToMany(relationship.isToMany());
+
             cayenneSrcDbEntity.addRelationship(dbRelationship);
             cayenneRelationship.addDbRelationship(dbRelationship);
 
-            return true;
+            return cayenneRelationship;
         }
     }
 

Modified: incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java?rev=399108&r1=399107&r2=399108&view=diff
==============================================================================
--- incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java (original)
+++ incubator/cayenne/jpa/trunk/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java Tue May  2 19:12:44 2006
@@ -267,12 +267,74 @@
         }
     }
 
+    final class JoinColumnVisitor extends BaseTreeVisitor {
+
+        @Override
+        public boolean onStartNode(ProjectPath path) {
+            JpaRelationship relationship = (JpaRelationship) path.getObjectParent();
+            JpaJoinColumn column = (JpaJoinColumn) path.getObject();
+
+            if (column.getTable() == null) {
+                JpaEntity entity = (JpaEntity) path.firstInstanceOf(JpaEntity.class);
+                column.setTable(entity.getTable().getName());
+            }
+
+            // JPA Spec, 2.1.8.2 (same for all relationship owners):
+            // The following mapping defaults apply: [...]
+            // Table A contains a foreign key to table B. The foreign key column
+            // name is formed as the concatenation of the following: the name of
+            // the relationship property or field of entityA; "_" ; the name of
+            // the primary key column in table B. The foreign key column has the
+            // same type as the primary key of table B.
+
+            JpaEntityMap map = (JpaEntityMap) path.firstInstanceOf(JpaEntityMap.class);
+            JpaEntity target = map.entityForClass(relationship.getTargetEntityName());
+
+            if (target == null) {
+                context.recordConflict(new SimpleValidationFailure(
+                        relationship,
+                        "Invalid relationship target "
+                                + relationship.getTargetEntityName()));
+            }
+            else if (target.getIds().isEmpty()) {
+                context.recordConflict(new SimpleValidationFailure(
+                        target,
+                        "Relationship target has no PK defined: "
+                                + relationship.getTargetEntityName()));
+            }
+            else if (target.getIds().size() > 1) {
+                // TODO: andrus, 4/30/2006 implement this; note that instead of
+                // checking for "attribute.getJoinColumns().isEmpty()" above,
+                // we'll have to match individual columns
+                context.recordConflict(new SimpleValidationFailure(
+                        relationship,
+                        "Defaults for compound FK are not implemented."));
+            }
+            else {
+                JpaId id = target.getIds().iterator().next();
+
+                String pkName = id.getColumn() != null ? id.getColumn().getName() : id
+                        .getName();
+                column.setName(relationship.getParent().getName() + '_' + pkName);
+                column.setReferencedColumnName(id.getColumn() != null ? id
+                        .getColumn()
+                        .getName() : id.getName());
+            }
+
+            return true;
+        }
+    }
+
     final class MappedSuperclassVisitor extends AbstractEntityVisitor {
 
     }
 
     final class FKVisitor extends RelationshipVisitor {
 
+        FKVisitor() {
+            addChildVisitor(JpaJoinColumn.class, new JoinColumnVisitor());
+        }
+
         @Override
         public boolean onStartNode(ProjectPath path) {
 
@@ -286,50 +348,9 @@
                 JpaRelationship relationship = (JpaRelationship) path.getObject();
 
                 if (relationship.isOwner()) {
-
-                    // JPA Spec, 2.1.8.2 (same for all relationship owners):
-                    // The following mapping defaults apply: [...]
-                    // Table A contains a foreign key to table B. The foreign key column
-                    // name is formed as the concatenation of the following: the name of
-                    // the relationship property or field of entityA; "_" ; the name of
-                    // the primary key column in table B. The foreign key column has the
-                    // same type as the primary key of table B.
-
-                    JpaEntityMap map = (JpaEntityMap) path
-                            .firstInstanceOf(JpaEntityMap.class);
-                    JpaEntity target = map.entityForClass(relationship
-                            .getTargetEntityName());
-
-                    if (target == null) {
-                        context.recordConflict(new SimpleValidationFailure(
-                                relationship,
-                                "Invalid relationship target "
-                                        + relationship.getTargetEntityName()));
-                    }
-                    else if (target.getIds().isEmpty()) {
-                        context.recordConflict(new SimpleValidationFailure(
-                                target,
-                                "Relationship target has no PK defined: "
-                                        + relationship.getTargetEntityName()));
-                    }
-                    else if (target.getIds().size() > 1) {
-                        // TODO: andrus, 4/30/2006 implement this; note that instead of
-                        // checking for "attribute.getJoinColumns().isEmpty()" above,
-                        // we'll have to match individual columns
-                        context.recordConflict(new SimpleValidationFailure(
-                                relationship,
-                                "Defaults for compound FK are not implemented."));
-                    }
-                    else {
-                        JpaId id = target.getIds().iterator().next();
-                        JpaJoinColumn joinColumn = new JpaJoinColumn(AnnotationPrototypes
-                                .getJoinColumn());
-
-                        String pkName = id.getColumn() != null
-                                ? id.getColumn().getName()
-                                : id.getName();
-                        joinColumn.setName(attribute.getName() + '_' + pkName);
-                    }
+                    JpaJoinColumn joinColumn = new JpaJoinColumn(AnnotationPrototypes
+                            .getJoinColumn());
+                    attribute.getJoinColumns().add(joinColumn);
                 }
             }
 

Modified: incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/bridge/DataMapMappingAssertion.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/bridge/DataMapMappingAssertion.java?rev=399108&r1=399107&r2=399108&view=diff
==============================================================================
--- incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/bridge/DataMapMappingAssertion.java (original)
+++ incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/bridge/DataMapMappingAssertion.java Tue May  2 19:12:44 2006
@@ -28,6 +28,7 @@
 import org.objectstyle.cayenne.map.DataMap;
 import org.objectstyle.cayenne.map.DbAttribute;
 import org.objectstyle.cayenne.map.DbEntity;
+import org.objectstyle.cayenne.map.DbRelationship;
 import org.objectstyle.cayenne.map.ObjAttribute;
 import org.objectstyle.cayenne.map.ObjEntity;
 import org.objectstyle.cayenne.map.ObjRelationship;
@@ -86,6 +87,8 @@
         DbAttribute column9 = (DbAttribute) table.getAttribute("column9");
         assertNotNull(column9);
         assertEquals(Types.DATE, column9.getType());
+
+        assertDbRelationship(table);
     }
 
     protected void assertObjAttributes(ObjEntity entity1) {
@@ -126,5 +129,23 @@
         assertFalse(attribute5.isToMany());
         assertEquals("attribute5", attribute5.getDbRelationshipPath());
         assertEquals("MockCayenneTargetEntity2", attribute5.getTargetEntityName());
+    }
+
+    protected void assertDbRelationship(DbEntity entity1) {
+        assertEquals(4, entity1.getRelationshipMap().size());
+
+        DbRelationship attribute4 = (DbRelationship) entity1
+                .getRelationship("attribute4");
+        assertNotNull(attribute4);
+        assertTrue(attribute4.isToMany());
+        assertEquals("MockCayenneTargetEntity2", attribute4.getTargetEntityName());
+        assertEquals(1, attribute4.getJoins().size());
+
+        DbRelationship attribute5 = (DbRelationship) entity1
+                .getRelationship("attribute5");
+        assertNotNull(attribute5);
+        assertFalse(attribute5.isToMany());
+        assertEquals("MockCayenneTargetEntity2", attribute5.getTargetEntityName());
+        assertEquals(1, attribute5.getJoins().size());
     }
 }

Modified: incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneEntity1.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneEntity1.java?rev=399108&r1=399107&r2=399108&view=diff
==============================================================================
--- incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneEntity1.java (original)
+++ incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneEntity1.java Tue May  2 19:12:44 2006
@@ -15,6 +15,7 @@
  */
 package org.apache.cayenne.jpa.entity.cayenne;
 
+import java.util.Collection;
 import java.util.Date;
 
 import javax.persistence.CascadeType;
@@ -36,6 +37,7 @@
 import javax.persistence.Transient;
 import javax.persistence.Version;
 
+import org.apache.cayenne.jpa.entity.MockTargetEntity2;
 import org.objectstyle.cayenne.CayenneDataObject;
 import org.objectstyle.cayenne.ObjectId;
 
@@ -63,10 +65,10 @@
     })
     protected int attribute3;
 
-    @OneToMany(targetEntity = MockCayenneTargetEntity2.class, fetch = FetchType.LAZY, mappedBy = "mb2", cascade = {
+    @OneToMany(targetEntity = MockCayenneTargetEntity2.class, fetch = FetchType.LAZY, mappedBy = "entity1", cascade = {
             CascadeType.MERGE, CascadeType.PERSIST
     })
-    protected int attribute4;
+    protected Collection<MockTargetEntity2> attribute4;
 
     @ManyToOne(targetEntity = MockCayenneTargetEntity2.class, fetch = FetchType.LAZY, optional = true, cascade = {
             CascadeType.MERGE, CascadeType.PERSIST
@@ -85,32 +87,26 @@
     @Temporal(TemporalType.DATE)
     protected Date attribute9;
 
-    
     public String getAttribute1() {
         return attribute1;
     }
 
-    
     public void setAttribute1(String attribute1) {
         this.attribute1 = attribute1;
     }
 
-    
     public int getAttribute2() {
         return attribute2;
     }
 
-    
     public void setAttribute2(int attribute2) {
         this.attribute2 = attribute2;
     }
 
-    
     public int getAttribute3() {
         return attribute3;
     }
 
-    
     public void setAttribute3(int attribute3) {
         this.attribute3 = attribute3;
     }

Modified: incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneTargetEntity2.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneTargetEntity2.java?rev=399108&r1=399107&r2=399108&view=diff
==============================================================================
--- incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneTargetEntity2.java (original)
+++ incubator/cayenne/jpa/trunk/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/entity/cayenne/MockCayenneTargetEntity2.java Tue May  2 19:12:44 2006
@@ -17,10 +17,14 @@
 
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 
 @Entity
 public class MockCayenneTargetEntity2 {
 
     @Id
     protected int targetId2;
+
+    @ManyToOne
+    protected MockCayenneEntity1 entity1;
 }