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 23:25:19 UTC
svn commit: r609229 - 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/
framework/cayenne-jpa-unpublished/src/main/java/or...
Author: aadamchik
Date: Sat Jan 5 14:25:17 2008
New Revision: 609229
URL: http://svn.apache.org/viewvc?rev=609229&view=rev
Log:
CAY-953 JPA: Single Table inheritance
(discriminator column mapping bridging...)
Added:
cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_10_1_SingleTablePerClassTest.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/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaDiscriminatorColumn.java
cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntity.java
cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_4_PrimaryKeyAndIdentityTest.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=609229&r1=609228&r2=609229&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 14:25:17 2008
@@ -21,10 +21,12 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
+import java.sql.Types;
import java.util.Iterator;
import javax.persistence.InheritanceType;
+import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.jpa.JpaProviderException;
import org.apache.cayenne.jpa.conf.EntityMapLoaderContext;
import org.apache.cayenne.jpa.map.AccessType;
@@ -33,6 +35,7 @@
import org.apache.cayenne.jpa.map.JpaAttributes;
import org.apache.cayenne.jpa.map.JpaBasic;
import org.apache.cayenne.jpa.map.JpaColumn;
+import org.apache.cayenne.jpa.map.JpaDiscriminatorColumn;
import org.apache.cayenne.jpa.map.JpaEmbeddable;
import org.apache.cayenne.jpa.map.JpaEmbedded;
import org.apache.cayenne.jpa.map.JpaEntity;
@@ -737,12 +740,13 @@
JpaEntity entity = path.firstInstanceOf(JpaEntity.class);
ObjEntity cayenneEntity = targetPath.firstInstanceOf(ObjEntity.class);
+ DbEntity cayennePrimaryTable = cayenneEntity.getDbEntity();
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());
@@ -778,6 +782,64 @@
dbRelationship.setToDependentPK(true);
dbRelationship.setToMany(false);
+ }
+
+ // init discriminator column
+ JpaDiscriminatorColumn discriminator = entity.lookupDiscriminatorColumn();
+ if (discriminator != null) {
+
+ if (cayennePrimaryTable.getAttribute(discriminator.getName()) == null) {
+ DbAttribute dbAttribute = new DbAttribute(discriminator.getName());
+
+ switch (discriminator.getDiscriminatorType()) {
+ case CHAR:
+ dbAttribute.setType(Types.CHAR);
+ dbAttribute.setMaxLength(1);
+ break;
+ case STRING:
+ dbAttribute.setType(Types.VARCHAR);
+ dbAttribute.setMaxLength(discriminator.getLength());
+ break;
+ case INTEGER:
+ dbAttribute.setType(Types.INTEGER);
+ break;
+ }
+
+ dbAttribute.setMandatory(false);
+ cayennePrimaryTable.addAttribute(dbAttribute);
+ }
+
+ String valueString = entity.getDiscriminatorValue();
+ if (valueString != null && valueString.length() > 0) {
+
+ Object value = null;
+ switch (discriminator.getDiscriminatorType()) {
+ case CHAR:
+ value = valueString.charAt(0);
+ break;
+ case STRING:
+ value = valueString;
+ break;
+ case INTEGER:
+ try {
+ value = Integer.valueOf(valueString);
+ }
+ catch (NumberFormatException e) {
+ recordConflict(
+ path,
+ "Invalid integer discriminator value '"
+ + valueString);
+ }
+ break;
+ }
+
+ if (value != null) {
+ cayenneEntity.setDeclaredQualifier(ExpressionFactory.matchDbExp(
+ discriminator.getName(),
+ value));
+ }
+
+ }
}
super.onFinishNode(path);
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=609229&r1=609228&r2=609229&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 14:25:17 2008
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.Date;
+import javax.persistence.DiscriminatorType;
import javax.persistence.EnumType;
import javax.persistence.InheritanceType;
import javax.persistence.TemporalType;
@@ -36,6 +37,7 @@
import org.apache.cayenne.jpa.map.JpaBasic;
import org.apache.cayenne.jpa.map.JpaClassDescriptor;
import org.apache.cayenne.jpa.map.JpaColumn;
+import org.apache.cayenne.jpa.map.JpaDiscriminatorColumn;
import org.apache.cayenne.jpa.map.JpaEmbeddable;
import org.apache.cayenne.jpa.map.JpaEntity;
import org.apache.cayenne.jpa.map.JpaEntityMap;
@@ -273,6 +275,29 @@
}
}
+ final class DiscriminatorColumnVisitor extends BaseTreeVisitor {
+
+ @Override
+ public boolean onStartNode(ProjectPath path) {
+
+ JpaDiscriminatorColumn column = (JpaDiscriminatorColumn) path.getObject();
+ if (column.getName() == null) {
+ column.setName("DTYPE");
+ }
+
+ if (column.getDiscriminatorType() == null) {
+ column.setDiscriminatorType(DiscriminatorType.STRING);
+ }
+
+ if (column.getLength() == 0
+ && column.getDiscriminatorType() == DiscriminatorType.STRING) {
+ column.setLength(31);
+ }
+
+ return false;
+ }
+ }
+
final class ColumnVisitor extends BaseTreeVisitor {
@Override
@@ -341,6 +366,12 @@
final class EntityVisitor extends AbstractEntityVisitor {
+ EntityVisitor() {
+ addChildVisitor(
+ JpaDiscriminatorColumn.class,
+ new DiscriminatorColumnVisitor());
+ }
+
@Override
public boolean onStartNode(ProjectPath path) {
if (super.onStartNode(path)) {
@@ -416,6 +447,24 @@
.getName());
}
}
+ }
+ }
+ }
+
+ JpaDiscriminatorColumn discriminator = entity.lookupDiscriminatorColumn();
+ if (discriminator != null) {
+
+ if (entity.getDiscriminatorValue() == null) {
+ switch (discriminator.getDiscriminatorType()) {
+
+ case STRING:
+ entity.setDiscriminatorValue(entity.getName());
+ break;
+ default:
+ context.recordConflict(new SimpleValidationFailure(
+ entity,
+ "Can't guess default discriminator value for non-String discriminator column: "
+ + discriminator.getName()));
}
}
}
Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaDiscriminatorColumn.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaDiscriminatorColumn.java?rev=609229&r1=609228&r2=609229&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaDiscriminatorColumn.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaDiscriminatorColumn.java Sat Jan 5 14:25:17 2008
@@ -39,9 +39,15 @@
}
public JpaDiscriminatorColumn(DiscriminatorColumn annotation) {
- name = annotation.name();
+ if (!"".equals(annotation.name())) {
+ name = annotation.name();
+ }
+
+ if (!"".equals(annotation.columnDefinition())) {
+ columnDefinition = annotation.columnDefinition();
+ }
+
discriminatorType = annotation.discriminatorType();
- columnDefinition = annotation.columnDefinition();
length = annotation.length();
}
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=609229&r1=609228&r2=609229&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 14:25:17 2008
@@ -256,11 +256,26 @@
if (table != null) {
return table;
}
-
- if(superEntity != null) {
+
+ if (superEntity != null) {
return superEntity.lookupTable();
}
-
+
+ return null;
+ }
+
+ /**
+ * Returns a discriminator column for this entity hierarchy.
+ */
+ public JpaDiscriminatorColumn lookupDiscriminatorColumn() {
+ if (discriminatorColumn != null) {
+ return discriminatorColumn;
+ }
+
+ if (superEntity != null) {
+ return superEntity.lookupDiscriminatorColumn();
+ }
+
return null;
}
Added: cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_10_1_SingleTablePerClassTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_10_1_SingleTablePerClassTest.java?rev=609229&view=auto
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_10_1_SingleTablePerClassTest.java (added)
+++ cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_10_1_SingleTablePerClassTest.java Sat Jan 5 14:25:17 2008
@@ -0,0 +1,77 @@
+/*****************************************************************
+ * 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.ch2;
+
+import org.apache.cayenne.itest.ItestTableUtils;
+import org.apache.cayenne.itest.jpa.EntityManagerCase;
+
+public class _2_1_10_1_SingleTablePerClassTest extends EntityManagerCase {
+
+ public void testSelectSuper() throws Exception {
+ ItestTableUtils helper = getTableHelper("ST_INHERITANCE");
+ helper.deleteAll();
+ helper.setColumns("id", "objectType", "propertyA", "propertyB", "propertyC");
+ helper.insert(1, "A", "1", null, null);
+ helper.insert(2, "A", "2", null, null);
+ helper.insert(3, "B", "3", "BX", null);
+ helper.insert(4, "C", "4", null, "CX");
+
+// Query query = getEntityManager().createQuery(
+// "select a FROM SingleTableInheritanceSuper1 a ORDER BY a.propertyA");
+// List<?> results = query.getResultList();
+// assertEquals(4, results.size());
+//
+// assertEquals(SingleTableInheritanceSuper1.class.getName(), results
+// .get(0)
+// .getClass()
+// .getName());
+// assertEquals(SingleTableInheritanceSuper1.class.getName(), results
+// .get(1)
+// .getClass()
+// .getName());
+// assertEquals(SingleTableInheritanceSub1.class.getName(), results
+// .get(2)
+// .getClass()
+// .getName());
+// assertEquals(SingleTableInheritanceSub2.class.getName(), results
+// .get(3)
+// .getClass()
+// .getName());
+ }
+
+ public void testSelectSub() throws Exception {
+ ItestTableUtils helper = getTableHelper("ST_INHERITANCE");
+ helper.deleteAll();
+ helper.setColumns("id", "objectType", "propertyA", "propertyB", "propertyC");
+ helper.insert(1, "A", "1", null, null);
+ helper.insert(2, "A", "2", null, null);
+ helper.insert(3, "B", "3", "BX", null);
+ helper.insert(4, "C", "4", null, "CX");
+
+// Query query = getEntityManager().createQuery(
+// "select a FROM SingleTableInheritanceSub1 a ORDER BY a.propertyA");
+// List<?> results = query.getResultList();
+// assertEquals(1, results.size());
+//
+// assertEquals(SingleTableInheritanceSub1.class.getName(), results
+// .get(0)
+// .getClass()
+// .getName());
+ }
+}
Modified: cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_4_PrimaryKeyAndIdentityTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_4_PrimaryKeyAndIdentityTest.java?rev=609229&r1=609228&r2=609229&view=diff
==============================================================================
--- cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_4_PrimaryKeyAndIdentityTest.java (original)
+++ cayenne/main/trunk/itests/jpa-chapter2/src/test/java/org/apache/cayenne/jpa/itest/ch2/_2_1_4_PrimaryKeyAndIdentityTest.java Sat Jan 5 14:25:17 2008
@@ -33,7 +33,6 @@
try {
getEntityManager().persist(o1);
-
}
catch (IllegalArgumentException e) {
return;