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 2007/12/24 01:04:46 UTC

svn commit: r606642 - in /cayenne/main/trunk: framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/ framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/ itests/jpa-chapter9/src/main/java/org/apache/cayen...

Author: aadamchik
Date: Sun Dec 23 16:04:45 2007
New Revision: 606642

URL: http://svn.apache.org/viewvc?rev=606642&view=rev
Log:
CAY-948 Implement flattened attributes in Cayenne
(support for SecondaryTable when bridging JPA to DataMap ... final bits that make the tests work for JPA)

Added:
    cayenne/main/trunk/itests/jpa-chapter9/src/main/java/org/apache/cayenne/jpa/itest/ch9/entity/SecondaryTableEntity.java
    cayenne/main/trunk/itests/jpa-chapter9/src/test/java/org/apache/cayenne/jpa/itest/ch9/_9_1_2_SecondaryTableAnnotationTest.java
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/itests/jpa-chapter9/src/main/resources/META-INF/persistence.xml
    cayenne/main/trunk/itests/jpa-chapter9/src/test/resources/schema-hsqldb.sql

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=606642&r1=606641&r2=606642&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 Sun Dec 23 16:04:45 2007
@@ -48,6 +48,7 @@
 import org.apache.cayenne.jpa.map.JpaOneToOne;
 import org.apache.cayenne.jpa.map.JpaPersistenceUnitDefaults;
 import org.apache.cayenne.jpa.map.JpaPersistenceUnitMetadata;
+import org.apache.cayenne.jpa.map.JpaPrimaryKeyJoinColumn;
 import org.apache.cayenne.jpa.map.JpaQueryHint;
 import org.apache.cayenne.jpa.map.JpaRelationship;
 import org.apache.cayenne.jpa.map.JpaSecondaryTable;
@@ -714,6 +715,55 @@
                         jpaEntity.getPreUpdate().getMethodName());
             }
         }
+
+        @Override
+        public void onFinishNode(ProjectPath path) {
+
+            JpaEntity entity = path.firstInstanceOf(JpaEntity.class);
+            ObjEntity cayenneEntity = targetPath.firstInstanceOf(ObjEntity.class);
+
+            for (JpaSecondaryTable secondaryTable : entity.getSecondaryTables()) {
+
+                // create a relationship between master DbEntity and a secondary
+                // DbEntity...
+                DbEntity cayennePrimaryTable = cayenneEntity.getDbEntity();
+                DbEntity cayenneSecondaryTable = cayennePrimaryTable
+                        .getDataMap()
+                        .getDbEntity(secondaryTable.getName());
+
+                JpaDbRelationship dbRelationship = new JpaDbRelationship(
+                        getSecondaryTableDbRelationshipName(secondaryTable.getName()));
+                dbRelationship.setTargetEntityName(secondaryTable.getName());
+                cayennePrimaryTable.addRelationship(dbRelationship);
+
+                for (JpaPrimaryKeyJoinColumn column : secondaryTable
+                        .getPrimaryKeyJoinColumns()) {
+                    DbAttribute pkAttribute = (DbAttribute) cayennePrimaryTable
+                            .getAttribute(column.getReferencedColumnName());
+                    if (pkAttribute == null) {
+                        recordConflict(path, "Invalid referenced column name: "
+                                + column.getReferencedColumnName());
+                        continue;
+                    }
+
+                    DbAttribute attribute = new DbAttribute(column.getName());
+                    attribute.setPrimaryKey(true);
+                    attribute.setMandatory(true);
+                    attribute.setAttributePrecision(pkAttribute.getAttributePrecision());
+                    attribute.setType(pkAttribute.getType());
+                    cayenneSecondaryTable.addAttribute(attribute);
+
+                    DbJoin join = new DbJoin(dbRelationship, column
+                            .getReferencedColumnName(), column.getName());
+                    dbRelationship.addJoin(join);
+                }
+
+                dbRelationship.setToDependentPK(true);
+                dbRelationship.setToMany(false);
+            }
+
+            super.onFinishNode(path);
+        }
     }
 
     class JpaManyToOneVisitor extends JpaRelationshipVisitor {
@@ -920,27 +970,20 @@
             JpaSecondaryTable jpaTable = (JpaSecondaryTable) path.getObject();
             ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
 
-            DbEntity cayenneEntity = parentCayenneEntity.getDataMap().getDbEntity(
+            DbEntity secondaryEntity = parentCayenneEntity.getDataMap().getDbEntity(
                     jpaTable.getName());
-            if (cayenneEntity == null) {
-                cayenneEntity = new DbEntity(jpaTable.getName());
-                cayenneEntity.setCatalog(jpaTable.getCatalog());
-                cayenneEntity.setSchema(jpaTable.getSchema());
+            if (secondaryEntity == null) {
+                secondaryEntity = new DbEntity(jpaTable.getName());
+                secondaryEntity.setCatalog(jpaTable.getCatalog());
+                secondaryEntity.setSchema(jpaTable.getSchema());
 
-                parentCayenneEntity.getDataMap().addDbEntity(cayenneEntity);
+                parentCayenneEntity.getDataMap().addDbEntity(secondaryEntity);
             }
 
-            // create a relationship between master DbEntity and a secondary DbEntity...
-            DbEntity masterEntity = parentCayenneEntity.getDbEntity();
-
-            JpaDbRelationship dbRelationship = new JpaDbRelationship(
-                    getSecondaryTableDbRelationshipName(cayenneEntity.getName()));
-            dbRelationship.setTargetEntityName(cayenneEntity.getName());
-            dbRelationship.setToMany(false);
+            // defer primary./secondary relationship creation till after parent entity's
+            // children are fully parsed...
 
-            masterEntity.addRelationship(dbRelationship);
-
-            return cayenneEntity;
+            return secondaryEntity;
         }
     }
 

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=606642&r1=606641&r2=606642&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 Sun Dec 23 16:04:45 2007
@@ -46,8 +46,10 @@
 import org.apache.cayenne.jpa.map.JpaMappedSuperclass;
 import org.apache.cayenne.jpa.map.JpaOneToMany;
 import org.apache.cayenne.jpa.map.JpaOneToOne;
+import org.apache.cayenne.jpa.map.JpaPrimaryKeyJoinColumn;
 import org.apache.cayenne.jpa.map.JpaPropertyDescriptor;
 import org.apache.cayenne.jpa.map.JpaRelationship;
+import org.apache.cayenne.jpa.map.JpaSecondaryTable;
 import org.apache.cayenne.jpa.map.JpaTable;
 import org.apache.cayenne.jpa.map.JpaVersion;
 import org.apache.cayenne.project.ProjectPath;
@@ -352,13 +354,50 @@
 
         EmbeddableVisitor() {
             BaseTreeVisitor attributeVisitor = new BaseTreeVisitor();
-            attributeVisitor.addChildVisitor(JpaBasic.class, new EmbeddableBasicVisitor());
+            attributeVisitor
+                    .addChildVisitor(JpaBasic.class, new EmbeddableBasicVisitor());
             addChildVisitor(JpaAttributes.class, attributeVisitor);
         }
     }
 
     final class EntityVisitor extends AbstractEntityVisitor {
 
+        @Override
+        public void onFinishNode(ProjectPath path) {
+
+            // now that attributes are parsed, we can fill in secondary table joins that
+            // may depend on previous entity id column processing.
+
+            JpaEntity entity = (JpaEntity) path.getObject();
+            for (JpaSecondaryTable table : entity.getSecondaryTables()) {
+
+                if (table.getPrimaryKeyJoinColumns().isEmpty()) {
+
+                    for (JpaId id : entity.getAttributes().getIds()) {
+                        JpaPrimaryKeyJoinColumn joinColumn = new JpaPrimaryKeyJoinColumn();
+                        joinColumn.setName(id.getColumn().getName());
+                        joinColumn.setReferencedColumnName(joinColumn.getName());
+                        table.getPrimaryKeyJoinColumns().add(joinColumn);
+                    }
+                }
+                else {
+                    for (JpaPrimaryKeyJoinColumn joinColumn : table
+                            .getPrimaryKeyJoinColumns()) {
+
+                        if (joinColumn.getReferencedColumnName() == null) {
+                            if (entity.getAttributes().getIds().size() == 1) {
+                                joinColumn.setReferencedColumnName(entity
+                                        .getAttributes()
+                                        .getIds()
+                                        .iterator()
+                                        .next()
+                                        .getName());
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     final class IdVisitor extends BaseTreeVisitor {

Added: cayenne/main/trunk/itests/jpa-chapter9/src/main/java/org/apache/cayenne/jpa/itest/ch9/entity/SecondaryTableEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter9/src/main/java/org/apache/cayenne/jpa/itest/ch9/entity/SecondaryTableEntity.java?rev=606642&view=auto
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter9/src/main/java/org/apache/cayenne/jpa/itest/ch9/entity/SecondaryTableEntity.java (added)
+++ cayenne/main/trunk/itests/jpa-chapter9/src/main/java/org/apache/cayenne/jpa/itest/ch9/entity/SecondaryTableEntity.java Sun Dec 23 16:04:45 2007
@@ -0,0 +1,60 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.cayenne.jpa.itest.ch9.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.SecondaryTable;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "PrimaryTable")
+@SecondaryTable(name = "SecondaryTable")
+public class SecondaryTableEntity {
+
+    @Id
+    protected int id;
+
+    @Column(table = "PrimaryTable")
+    protected String primaryTableProperty;
+
+    @Column(table = "SecondaryTable")
+    protected String secondaryTableProperty;
+
+    public int getId() {
+        return id;
+    }
+
+    public String getPrimaryTableProperty() {
+        return primaryTableProperty;
+    }
+
+    public void setPrimaryTableProperty(String primaryTableProperty) {
+        this.primaryTableProperty = primaryTableProperty;
+    }
+
+    public String getSecondaryTableProperty() {
+        return secondaryTableProperty;
+    }
+
+    public void setSecondaryTableProperty(String secondaryTableProperty) {
+        this.secondaryTableProperty = secondaryTableProperty;
+    }
+}

Modified: cayenne/main/trunk/itests/jpa-chapter9/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter9/src/main/resources/META-INF/persistence.xml?rev=606642&r1=606641&r2=606642&view=diff
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter9/src/main/resources/META-INF/persistence.xml (original)
+++ cayenne/main/trunk/itests/jpa-chapter9/src/main/resources/META-INF/persistence.xml Sun Dec 23 16:04:45 2007
@@ -24,5 +24,6 @@
 		<class>org.apache.cayenne.jpa.itest.ch9.entity.IdEntity</class>
 		<class>org.apache.cayenne.jpa.itest.ch9.entity.IdColumnEntity</class>
 		<class>org.apache.cayenne.jpa.itest.ch9.entity.BasicEntity</class>
+		<class>org.apache.cayenne.jpa.itest.ch9.entity.SecondaryTableEntity</class>
 	</persistence-unit>
 </persistence>

Added: cayenne/main/trunk/itests/jpa-chapter9/src/test/java/org/apache/cayenne/jpa/itest/ch9/_9_1_2_SecondaryTableAnnotationTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter9/src/test/java/org/apache/cayenne/jpa/itest/ch9/_9_1_2_SecondaryTableAnnotationTest.java?rev=606642&view=auto
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter9/src/test/java/org/apache/cayenne/jpa/itest/ch9/_9_1_2_SecondaryTableAnnotationTest.java (added)
+++ cayenne/main/trunk/itests/jpa-chapter9/src/test/java/org/apache/cayenne/jpa/itest/ch9/_9_1_2_SecondaryTableAnnotationTest.java Sun Dec 23 16:04:45 2007
@@ -0,0 +1,43 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.cayenne.jpa.itest.ch9;
+
+import org.apache.cayenne.itest.jpa.EntityManagerCase;
+import org.apache.cayenne.jpa.itest.ch9.entity.SecondaryTableEntity;
+
+public class _9_1_2_SecondaryTableAnnotationTest extends EntityManagerCase {
+
+    public void testPersist() throws Exception {
+        getDbHelper().deleteAll("SecondaryTable");
+        getDbHelper().deleteAll("PrimaryTable");
+
+        SecondaryTableEntity o1 = new SecondaryTableEntity();
+        o1.setPrimaryTableProperty("p1");
+        o1.setSecondaryTableProperty("s1");
+
+        getEntityManager().persist(o1);
+        getEntityManager().getTransaction().commit();
+        
+        assertTrue(o1.getId() > 0);
+
+        assertEquals("p1", getDbHelper().getObject("PrimaryTable", "primaryTableProperty"));
+        assertEquals("s1", getDbHelper().getObject("SecondaryTable", "secondaryTableProperty"));
+        assertEquals(o1.getId(), getDbHelper().getObject("SecondaryTable", "id"));
+    }
+}

Modified: cayenne/main/trunk/itests/jpa-chapter9/src/test/resources/schema-hsqldb.sql
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter9/src/test/resources/schema-hsqldb.sql?rev=606642&r1=606641&r2=606642&view=diff
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter9/src/test/resources/schema-hsqldb.sql (original)
+++ cayenne/main/trunk/itests/jpa-chapter9/src/test/resources/schema-hsqldb.sql Sun Dec 23 16:04:45 2007
@@ -2,7 +2,10 @@
 insert into AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('IdEntity', 1);
 insert into AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('IdColumnEntity', 1);
 insert into AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('BasicEntity', 1);
+insert into AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('PrimaryTable', 1);
 
 create table IdEntity (id int not null, primary key(id));
 create table IdColumnEntity (idcolumn int not null, primary key(idcolumn));
-create table BasicEntity (id int not null, basicDefault VARCHAR(100), basicDefaultInt INTEGER, basicEager VARCHAR(100), basicLazy VARCHAR(100), primary key(id));
\ No newline at end of file
+create table BasicEntity (id int not null, basicDefault VARCHAR(100), basicDefaultInt INTEGER, basicEager VARCHAR(100), basicLazy VARCHAR(100), primary key(id));
+create table PrimaryTable(id int not null, primaryTableProperty VARCHAR(100), primary key (id));
+create table SecondaryTable(id int not null, secondaryTableProperty VARCHAR(100), primary key (id));
\ No newline at end of file