cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject cayenne git commit: CAY-2381 cgen: meaningful PK with boxed type ends up with primitive type in generated source
Date Fri, 08 Dec 2017 08:38:53 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master e0b9ebecc -> 74ff3fdeb


CAY-2381 cgen: meaningful PK with boxed type ends up with primitive type in generated source

 closes #249


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

Branch: refs/heads/master
Commit: 74ff3fdeb06c4f0140f27e4852f8fd4ba86ba57b
Parents: e0b9ebe
Author: Nikita Timofeev <stariy95@gmail.com>
Authored: Fri Dec 8 11:36:17 2017 +0300
Committer: Nikita Timofeev <stariy95@gmail.com>
Committed: Fri Dec 8 11:38:25 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/gen/ImportUtils.java     | 131 ++++++++++---------
 .../resources/templates/v4_1/singleclass.vm     |  13 +-
 .../main/resources/templates/v4_1/superclass.vm |  13 +-
 .../DataContextEntityWithMeaningfulPKIT.java    | 131 ++++++++++++++-----
 .../testdo/meaningful_pk/MeaningfulPkTest2.java |   9 ++
 .../meaningful_pk/auto/_MeaningfulPKTest1.java  |  53 +++++++-
 .../meaningful_pk/auto/_MeaningfulPkTest2.java  | 124 ++++++++++++++++++
 .../test/resources/cayenne-meaningful-pk.xml    |   3 +
 .../src/test/resources/meaningful-pk.graph.xml  |   9 ++
 .../src/test/resources/meaningful-pk.map.xml    |  16 ++-
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 11 files changed, 387 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ImportUtils.java
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ImportUtils.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ImportUtils.java
index f178b76..275a535 100644
--- a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ImportUtils.java
+++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/ImportUtils.java
@@ -19,11 +19,10 @@
 
 package org.apache.cayenne.gen;
 
+import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.util.Util;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -34,10 +33,9 @@ import java.util.Map;
  */
 public class ImportUtils {
 
-	public static final String importOrdering[] = new String[] { "java.", "javax.", "org.",
"com." };
+	public static final String importOrdering[] = { "java.", "javax.", "org.", "com." };
 
-	static final String primitives[] = new String[] { "long", "double", "byte", "boolean", "float",
"short", "int",
-			"char" };
+	static final String primitives[] = { "long", "double", "byte", "boolean", "float", "short",
"int", "char" };
 
 	static final String primitiveClasses[] = new String[] { Long.class.getName(), Double.class.getName(),
 			Byte.class.getName(), Boolean.class.getName(), Float.class.getName(), Short.class.getName(),
@@ -53,32 +51,29 @@ public class ImportUtils {
 
 	protected String packageName;
 
-	public ImportUtils() {
-		super();
-	}
-
 	protected boolean canRegisterType(String typeName) {
 		// Not sure why this would ever happen, but it did
-		if (null == typeName)
-			return false;
+		if (null == typeName) {
+            return false;
+        }
 
 		StringUtils stringUtils = StringUtils.getInstance();
 		String typeClassName = stringUtils.stripPackageName(typeName);
 		String typePackageName = stringUtils.stripClass(typeName);
 
-		if (typePackageName.length() == 0)
-			return false; // disallow non-packaged types (primitives, probably)
-		if ("java.lang".equals(typePackageName))
-			return false;
+		if (typePackageName.length() == 0) {
+            return false; // disallow non-packaged types (primitives, probably)
+        }
+		if ("java.lang".equals(typePackageName)) {
+            return false;
+        }
 
 		// Can only have one type -- rest must use fqn
-		if (reservedImportTypesMap.containsKey(typeClassName))
-			return false;
-		if (importTypesMap.containsKey(typeClassName))
-			return false;
-
-		return true;
-	}
+		if (reservedImportTypesMap.containsKey(typeClassName)) {
+            return false;
+        }
+        return !importTypesMap.containsKey(typeClassName);
+    }
 
 	/**
 	 * Reserve a fully-qualified data type class name so it cannot be used by
@@ -90,8 +85,9 @@ public class ImportUtils {
 	 *            FQ data type class name.
 	 */
 	public void addReservedType(String typeName) {
-		if (!canRegisterType(typeName))
-			return;
+		if (!canRegisterType(typeName)) {
+            return;
+        }
 
 		StringUtils stringUtils = StringUtils.getInstance();
 		String typeClassName = stringUtils.stripPackageName(typeName);
@@ -107,23 +103,21 @@ public class ImportUtils {
 	 *            FQ data type class name.
 	 */
 	public void addType(String typeName) {
-		if (!canRegisterType(typeName))
-			return;
+		if (!canRegisterType(typeName)) {
+            return;
+        }
 
 		StringUtils stringUtils = StringUtils.getInstance();
 		String typePackageName = stringUtils.stripClass(typeName);
-		String typeClassName = stringUtils.stripPackageName(typeName);
+		if (typePackageName.equals(packageName)) {
+            return;
+        }
 
-		if (typePackageName.equals(packageName))
-			return;
-
-		importTypesMap.put(typeClassName, typeName);
+		importTypesMap.put(stringUtils.stripPackageName(typeName), typeName);
 	}
 
 	/**
 	 * Add the package name to use for this importUtil invocation.
-	 * 
-	 * @param packageName
 	 */
 	public void setPackage(String packageName) {
 		this.packageName = packageName;
@@ -154,18 +148,19 @@ public class ImportUtils {
 			StringUtils stringUtils = StringUtils.getInstance();
 			String typeClassName = stringUtils.stripPackageName(typeName);
 
-			if (!reservedImportTypesMap.containsKey(typeClassName)) {
-				if (importTypesMap.containsKey(typeClassName)) {
-					if (typeName.equals(importTypesMap.get(typeClassName)))
-						return typeClassName;
-				}
+			if (!reservedImportTypesMap.containsKey(typeClassName)
+                && importTypesMap.containsKey(typeClassName)
+                    && typeName.equals(importTypesMap.get(typeClassName))) {
+			    return typeClassName;
 			}
 
 			String typePackageName = stringUtils.stripClass(typeName);
-			if ("java.lang".equals(typePackageName))
-				return typeClassName;
-			if ((null != packageName) && (packageName.equals(typePackageName)))
-				return typeClassName;
+			if ("java.lang".equals(typePackageName)) {
+                return typeClassName;
+            }
+			if ((null != packageName) && (packageName.equals(typePackageName))) {
+                return typeClassName;
+            }
 		}
 
 		return typeName;
@@ -203,6 +198,22 @@ public class ImportUtils {
 	}
 
 	/**
+	 *
+	 * This method decide can primitive type be used for given attribute.
+	 * It can be used in following cases:
+	 * 		- attribute is PK and primitive
+	 * 		- attribute not PK and is mandatory
+	 *
+	 * @param attribute to check
+	 * @return can primitive Java type be used
+	 *
+	 * @since 4.1
+	 */
+	public boolean canUsePrimitive(ObjAttribute attribute) {
+        return attribute.isMandatory() && isPrimitive(attribute.getType());
+    }
+
+	/**
 	 * Generate package and list of import statements based on the registered
 	 * types.
 	 */
@@ -213,31 +224,25 @@ public class ImportUtils {
 			outputBuffer.append("package ");
 			outputBuffer.append(packageName);
 
-			// Using UNIX line endings intentionally - generated Java files
-			// should look
-			// the same regardless of platform to prevent developer teams
-			// working on
+			// Using UNIX line endings intentionally - generated Java files should look
+			// the same regardless of platform to prevent developer teams working on
 			// multiple OS's to override each other's work
 			outputBuffer.append(";\n\n");
 		}
 
 		List<String> typesList = new ArrayList<>(importTypesMap.values());
-		Collections.sort(typesList, new Comparator<String>() {
-
-			public int compare(String s1, String s2) {
-
-				for (String ordering : importOrdering) {
-					if ((s1.startsWith(ordering)) && (!s2.startsWith(ordering))) {
-						return -1;
-					}
-					if ((!s1.startsWith(ordering)) && (s2.startsWith(ordering))) {
-						return 1;
-					}
-				}
-
-				return s1.compareTo(s2);
-			}
-		});
+		typesList.sort((s1, s2) -> {
+            for (String ordering : importOrdering) {
+                if ((s1.startsWith(ordering)) && (!s2.startsWith(ordering))) {
+                    return -1;
+                }
+                if ((!s1.startsWith(ordering)) && (s2.startsWith(ordering))) {
+                    return 1;
+                }
+            }
+
+            return s1.compareTo(s2);
+        });
 
 		String lastStringPrefix = null;
 		boolean firstIteration = true;
@@ -258,7 +263,7 @@ public class ImportUtils {
 			// if this isn't the first import,
 			if (null != lastStringPrefix) {
 				// and it's different from the last import
-				if (false == thisStringPrefix.equals(lastStringPrefix)) {
+				if (!thisStringPrefix.equals(lastStringPrefix)) {
 					// output a newline; force UNIX style per comment above
 					outputBuffer.append("\n");
 				}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-cgen/src/main/resources/templates/v4_1/singleclass.vm
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/resources/templates/v4_1/singleclass.vm b/cayenne-cgen/src/main/resources/templates/v4_1/singleclass.vm
index 40d6ef0..b9285a8 100644
--- a/cayenne-cgen/src/main/resources/templates/v4_1/singleclass.vm
+++ b/cayenne-cgen/src/main/resources/templates/v4_1/singleclass.vm
@@ -101,8 +101,8 @@ public#if("true" == "${object.isAbstract()}") abstract#end class ${subClassName}
 ## Create Fields ##
 ###################
 #foreach( $attr in ${object.DeclaredAttributes} )
-## don't use primitive type if attribute is nullable
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
     protected $type $stringUtils.formatVariableName(${attr.Name});
 #end
 
@@ -227,8 +227,9 @@ public#if("true" == "${object.isAbstract()}") abstract#end class ${subClassName}
 
         switch (propName) {
 #foreach( $attr in ${object.DeclaredAttributes} )
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
             case "${attr.Name}":
 #if ( $importUtils.isBoolean($type) )
                 this.${name} = val == null ? false : ($type)val;
@@ -265,7 +266,8 @@ public#if("true" == "${object.isAbstract()}") abstract#end class ${subClassName}
         super.writeState(out);
 #foreach( $attr in ${object.DeclaredAttributes} )
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
 #if($importUtils.isPrimitive($type))
         out.write${stringUtils.capitalized($type)}(this.$name);
 #else
@@ -282,7 +284,8 @@ public#if("true" == "${object.isAbstract()}") abstract#end class ${subClassName}
         super.readState(in);
 #foreach( $attr in ${object.DeclaredAttributes} )
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
 #if($importUtils.isPrimitive($type))
         this.$name = in.read${stringUtils.capitalized($type)}();
 #else

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-cgen/src/main/resources/templates/v4_1/superclass.vm
----------------------------------------------------------------------
diff --git a/cayenne-cgen/src/main/resources/templates/v4_1/superclass.vm b/cayenne-cgen/src/main/resources/templates/v4_1/superclass.vm
index 97c9716..91152d7 100644
--- a/cayenne-cgen/src/main/resources/templates/v4_1/superclass.vm
+++ b/cayenne-cgen/src/main/resources/templates/v4_1/superclass.vm
@@ -109,8 +109,8 @@ public abstract class ${superClassName} extends ${baseClassName} {
 ## Create Fields ##
 ###################
 #foreach( $attr in ${object.DeclaredAttributes} )
-## don't use primitive type if attribute is nullable
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)" )
     protected $type $stringUtils.formatVariableName(${attr.Name});
 #end
 
@@ -233,8 +233,9 @@ public abstract class ${superClassName} extends ${baseClassName} {
 
         switch (propName) {
 #foreach( $attr in ${object.DeclaredAttributes} )
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
             case "${attr.Name}":
 #if ( $importUtils.isBoolean($type) )
                 this.${name} = val == null ? false : ($type)val;
@@ -271,7 +272,8 @@ public abstract class ${superClassName} extends ${baseClassName} {
         super.writeState(out);
 #foreach( $attr in ${object.DeclaredAttributes} )
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
 #if($importUtils.isPrimitive($type))
         out.write${stringUtils.capitalized($type)}(this.$name);
 #else
@@ -288,7 +290,8 @@ public abstract class ${superClassName} extends ${baseClassName} {
         super.readState(in);
 #foreach( $attr in ${object.DeclaredAttributes} )
 #set ( $name = "$stringUtils.formatVariableName(${attr.Name})")
-#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $attr.isMandatory())")
+#set ( $flag = $importUtils.canUsePrimitive($attr) )
+#set ( $type = "$importUtils.formatJavaType(${attr.Type}, $flag)")
 #if($importUtils.isPrimitive($type))
         this.$name = in.read${stringUtils.capitalized($type)}();
 #else

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
index 0b93031..ee5c87b 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
@@ -20,14 +20,16 @@
 package org.apache.cayenne.access;
 
 import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.query.ObjectIdQuery;
-import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep;
 import org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1;
+import org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkTest2;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
 import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -36,10 +38,7 @@ import org.junit.Test;
 import java.util.List;
 import java.util.Map;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 @UseServerRuntime(CayenneProjects.MEANINGFUL_PK_PROJECT)
 public class DataContextEntityWithMeaningfulPKIT extends ServerCase {
@@ -52,82 +51,142 @@ public class DataContextEntityWithMeaningfulPKIT extends ServerCase {
     private ServerRuntime runtime;
 
     @Test
-    public void testInsertWithMeaningfulPK() throws Exception {
+    public void testInsertWithMeaningfulPK() {
         MeaningfulPKTest1 obj = context.newObject(MeaningfulPKTest1.class);
         obj.setPkAttribute(1000);
         obj.setDescr("aaa-aaa");
         context.commitChanges();
-        ObjectIdQuery q = new ObjectIdQuery(new ObjectId(
-                "MeaningfulPKTest1",
-                MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN,
-                1000), true, ObjectIdQuery.CACHE_REFRESH);
-        assertEquals(1, context.performQuery(q).size());
+        ObjectId objId = new ObjectId("MeaningfulPKTest1", MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN,
1000);
+        ObjectIdQuery q = new ObjectIdQuery(objId, true, ObjectIdQuery.CACHE_REFRESH);
+        @SuppressWarnings("unchecked")
+        List<DataRow> result = (List<DataRow>)context.performQuery(q);
+        assertEquals(1, result.size());
+        assertEquals(1000, result.get(0).get(MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN));
     }
 
     @Test
-    public void testGeneratedKey() throws Exception {
+    public void testGeneratedKey() {
         MeaningfulPKTest1 obj = context.newObject(MeaningfulPKTest1.class);
         obj.setDescr("aaa-aaa");
         context.commitChanges();
 
-        assertNotNull(obj.getPkAttribute());
-        assertSame(obj, Cayenne.objectForPK(context, MeaningfulPKTest1.class, obj
-                .getPkAttribute()));
+        assertNotEquals(0, obj.getPkAttribute());
+        assertSame(obj, Cayenne.objectForPK(context, MeaningfulPKTest1.class, obj.getPkAttribute()));
 
         int id = Cayenne.intPKForObject(obj);
 
-        Map snapshot = context.getObjectStore().getDataRowCache().getCachedSnapshot(
-                obj.getObjectId());
+        Map snapshot = context.getObjectStore().getDataRowCache().getCachedSnapshot(obj.getObjectId());
         assertNotNull(snapshot);
         assertTrue(snapshot.containsKey(MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN));
-        assertEquals(new Integer(id), snapshot
-                .get(MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN));
+        assertEquals(id, snapshot.get(MeaningfulPKTest1.PK_ATTRIBUTE_PK_COLUMN));
     }
 
     @Test
-    public void testChangeKey() throws Exception {
-        MeaningfulPKTest1 obj = (MeaningfulPKTest1) context
-                .newObject("MeaningfulPKTest1");
-        obj.setPkAttribute(new Integer(1000));
+    public void testChangeKey() {
+        MeaningfulPKTest1 obj = context.newObject(MeaningfulPKTest1.class);
+        obj.setPkAttribute(1000);
         obj.setDescr("aaa-aaa");
         context.commitChanges();
 
-        obj.setPkAttribute(new Integer(2000));
+        obj.setPkAttribute(2000);
         context.commitChanges();
 
         // assert that object id got fixed
         ObjectId id = obj.getObjectId();
-        assertEquals(new Integer(2000), id.getIdSnapshot().get("PK_ATTRIBUTE"));
+        assertEquals(2000, id.getIdSnapshot().get("PK_ATTRIBUTE"));
     }
 
     @Test
-    public void testToManyRelationshipWithMeaningfulPK1() throws Exception {
-        MeaningfulPKTest1 obj = (MeaningfulPKTest1) context
-                .newObject("MeaningfulPKTest1");
-        obj.setPkAttribute(new Integer(1000));
+    public void testToManyRelationshipWithMeaningfulPK1() {
+        MeaningfulPKTest1 obj = context.newObject(MeaningfulPKTest1.class);
+        obj.setPkAttribute(1000);
         obj.setDescr("aaa-aaa");
         context.commitChanges();
 
         // must be able to resolve to-many relationship
         ObjectContext context = runtime.newContext();
-        List objects = context.performQuery(new SelectQuery(MeaningfulPKTest1.class));
+        List<MeaningfulPKTest1> objects = ObjectSelect.query(MeaningfulPKTest1.class).select(context);
         assertEquals(1, objects.size());
-        obj = (MeaningfulPKTest1) objects.get(0);
+        obj = objects.get(0);
         assertEquals(0, obj.getMeaningfulPKDepArray().size());
     }
 
     @Test
-    public void testToManyRelationshipWithMeaningfulPK2() throws Exception {
-        MeaningfulPKTest1 obj = (MeaningfulPKTest1) context
-                .newObject("MeaningfulPKTest1");
-        obj.setPkAttribute(new Integer(1000));
+    public void testToManyRelationshipWithMeaningfulPK2() {
+        MeaningfulPKTest1 obj = context.newObject(MeaningfulPKTest1.class);
+        obj.setPkAttribute(1000);
         obj.setDescr("aaa-aaa");
         context.commitChanges();
 
         // must be able to set reverse relationship
-        MeaningfulPKDep dep = (MeaningfulPKDep) context.newObject("MeaningfulPKDep");
+        MeaningfulPKDep dep = context.newObject(MeaningfulPKDep.class);
         dep.setToMeaningfulPK(obj);
         context.commitChanges();
     }
 
+    @Test
+    public void testGeneratedIntegerPK(){
+        MeaningfulPkTest2 obj1 = context.newObject(MeaningfulPkTest2.class);
+        obj1.setIntegerAttribute(10);
+        MeaningfulPkTest2 obj2 = context.newObject(MeaningfulPkTest2.class);
+        obj2.setIntegerAttribute(20);
+        context.commitChanges();
+
+        ObjectContext context = runtime.newContext();
+        List<MeaningfulPkTest2> objects = ObjectSelect.query(MeaningfulPkTest2.class).select(context);
+        assertEquals(2, objects.size());
+        assertNotEquals(Integer.valueOf(0), obj1.getPkAttribute());
+        assertNotEquals(Integer.valueOf(0), obj2.getPkAttribute());
+        assertNotEquals(obj1.getPkAttribute(), obj2.getPkAttribute());
+    }
+
+    @Test
+    public void testMeaningfulIntegerPK(){
+        MeaningfulPkTest2 obj1 = context.newObject(MeaningfulPkTest2.class);
+        obj1.setIntegerAttribute(10);
+        obj1.setPkAttribute(1);
+        MeaningfulPkTest2 obj2 = context.newObject(MeaningfulPkTest2.class);
+        obj2.setIntegerAttribute(20);
+        obj2.setPkAttribute(2);
+        context.commitChanges();
+
+        ObjectContext context = runtime.newContext();
+        List<MeaningfulPkTest2> objects = ObjectSelect.query(MeaningfulPkTest2.class).select(context);
+        assertEquals(2, objects.size());
+        assertEquals(Integer.valueOf(1), obj1.getPkAttribute());
+        assertEquals(Integer.valueOf(2), obj2.getPkAttribute());
+    }
+
+    @Test
+    public void testGeneratedIntPK(){
+        MeaningfulPKTest1 obj1 = context.newObject(MeaningfulPKTest1.class);
+        obj1.setIntAttribute(10);
+        MeaningfulPKTest1 obj2 = context.newObject(MeaningfulPKTest1.class);
+        obj2.setIntAttribute(20);
+        context.commitChanges();
+
+        ObjectContext context = runtime.newContext();
+        List<MeaningfulPKTest1> objects = ObjectSelect.query(MeaningfulPKTest1.class).select(context);
+        assertEquals(2, objects.size());
+        assertNotEquals(0, obj1.getPkAttribute());
+        assertNotEquals(0, obj2.getPkAttribute());
+        assertNotEquals(obj1.getPkAttribute(), obj2.getPkAttribute());
+    }
+
+    @Test
+    public void testMeaningfulIntPK(){
+        MeaningfulPKTest1 obj1 = context.newObject(MeaningfulPKTest1.class);
+        obj1.setIntAttribute(10);
+        obj1.setPkAttribute(1);
+        MeaningfulPKTest1 obj2 = context.newObject(MeaningfulPKTest1.class);
+        obj2.setIntAttribute(20);
+        obj2.setPkAttribute(2);
+        context.commitChanges();
+
+        ObjectContext context = runtime.newContext();
+        List<MeaningfulPKTest1> objects = ObjectSelect.query(MeaningfulPKTest1.class).select(context);
+        assertEquals(2, objects.size());
+        assertEquals(1, obj1.getPkAttribute());
+        assertEquals(2, obj2.getPkAttribute());
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/MeaningfulPkTest2.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/MeaningfulPkTest2.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/MeaningfulPkTest2.java
new file mode 100644
index 0000000..b67c685
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/MeaningfulPkTest2.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.meaningful_pk;
+
+import org.apache.cayenne.testdo.meaningful_pk.auto._MeaningfulPkTest2;
+
+public class MeaningfulPkTest2 extends _MeaningfulPkTest2 {
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPKTest1.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPKTest1.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPKTest1.java
index 9e994d3..c4e3a82 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPKTest1.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPKTest1.java
@@ -22,11 +22,15 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
     public static final String PK_ATTRIBUTE_PK_COLUMN = "PK_ATTRIBUTE";
 
     public static final Property<String> DESCR = Property.create("descr", String.class);
+    public static final Property<Integer> INT_ATTRIBUTE = Property.create("intAttribute",
Integer.class);
+    public static final Property<Integer> INT_NULLABLE_ATTRIBUTE = Property.create("intNullableAttribute",
Integer.class);
     public static final Property<Integer> PK_ATTRIBUTE = Property.create("pkAttribute",
Integer.class);
     public static final Property<List<MeaningfulPKDep>> MEANINGFUL_PKDEP_ARRAY
= Property.create("meaningfulPKDepArray", List.class);
 
     protected String descr;
-    protected Integer pkAttribute;
+    protected int intAttribute;
+    protected Integer intNullableAttribute;
+    protected int pkAttribute;
 
     protected Object meaningfulPKDepArray;
 
@@ -40,12 +44,35 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
         return this.descr;
     }
 
-    public void setPkAttribute(Integer pkAttribute) {
+    public void setIntAttribute(int intAttribute) {
+        beforePropertyWrite("intAttribute", this.intAttribute, intAttribute);
+        this.intAttribute = intAttribute;
+    }
+
+    public int getIntAttribute() {
+        beforePropertyRead("intAttribute");
+        return this.intAttribute;
+    }
+
+    public void setIntNullableAttribute(int intNullableAttribute) {
+        beforePropertyWrite("intNullableAttribute", this.intNullableAttribute, intNullableAttribute);
+        this.intNullableAttribute = intNullableAttribute;
+    }
+
+    public int getIntNullableAttribute() {
+        beforePropertyRead("intNullableAttribute");
+        if(this.intNullableAttribute == null) {
+            return 0;
+        }
+        return this.intNullableAttribute;
+    }
+
+    public void setPkAttribute(int pkAttribute) {
         beforePropertyWrite("pkAttribute", this.pkAttribute, pkAttribute);
         this.pkAttribute = pkAttribute;
     }
 
-    public Integer getPkAttribute() {
+    public int getPkAttribute() {
         beforePropertyRead("pkAttribute");
         return this.pkAttribute;
     }
@@ -72,6 +99,10 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
         switch(propName) {
             case "descr":
                 return this.descr;
+            case "intAttribute":
+                return this.intAttribute;
+            case "intNullableAttribute":
+                return this.intNullableAttribute;
             case "pkAttribute":
                 return this.pkAttribute;
             case "meaningfulPKDepArray":
@@ -91,8 +122,14 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
             case "descr":
                 this.descr = (String)val;
                 break;
+            case "intAttribute":
+                this.intAttribute = val == null ? 0 : (int)val;
+                break;
+            case "intNullableAttribute":
+                this.intNullableAttribute = (Integer)val;
+                break;
             case "pkAttribute":
-                this.pkAttribute = (Integer)val;
+                this.pkAttribute = val == null ? 0 : (int)val;
                 break;
             case "meaningfulPKDepArray":
                 this.meaningfulPKDepArray = val;
@@ -114,7 +151,9 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
     protected void writeState(ObjectOutputStream out) throws IOException {
         super.writeState(out);
         out.writeObject(this.descr);
-        out.writeObject(this.pkAttribute);
+        out.writeInt(this.intAttribute);
+        out.writeObject(this.intNullableAttribute);
+        out.writeInt(this.pkAttribute);
         out.writeObject(this.meaningfulPKDepArray);
     }
 
@@ -122,7 +161,9 @@ public abstract class _MeaningfulPKTest1 extends BaseDataObject {
     protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException
{
         super.readState(in);
         this.descr = (String)in.readObject();
-        this.pkAttribute = (Integer)in.readObject();
+        this.intAttribute = in.readInt();
+        this.intNullableAttribute = (Integer)in.readObject();
+        this.pkAttribute = in.readInt();
         this.meaningfulPKDepArray = in.readObject();
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPkTest2.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPkTest2.java
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPkTest2.java
new file mode 100644
index 0000000..c0ab9d2
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/meaningful_pk/auto/_MeaningfulPkTest2.java
@@ -0,0 +1,124 @@
+package org.apache.cayenne.testdo.meaningful_pk.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _MeaningfulPkTest2 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _MeaningfulPkTest2 extends BaseDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String PK_ATTRIBUTE_PK_COLUMN = "PK_ATTRIBUTE";
+
+    public static final Property<Integer> INTEGER_ATTRIBUTE = Property.create("integerAttribute",
Integer.class);
+    public static final Property<Integer> INTEGER_NULLABLE_ATTRIBUTE = Property.create("integerNullableAttribute",
Integer.class);
+    public static final Property<Integer> PK_ATTRIBUTE = Property.create("pkAttribute",
Integer.class);
+
+    protected Integer integerAttribute;
+    protected Integer integerNullableAttribute;
+    protected Integer pkAttribute;
+
+
+    public void setIntegerAttribute(Integer integerAttribute) {
+        beforePropertyWrite("integerAttribute", this.integerAttribute, integerAttribute);
+        this.integerAttribute = integerAttribute;
+    }
+
+    public Integer getIntegerAttribute() {
+        beforePropertyRead("integerAttribute");
+        return this.integerAttribute;
+    }
+
+    public void setIntegerNullableAttribute(Integer integerNullableAttribute) {
+        beforePropertyWrite("integerNullableAttribute", this.integerNullableAttribute, integerNullableAttribute);
+        this.integerNullableAttribute = integerNullableAttribute;
+    }
+
+    public Integer getIntegerNullableAttribute() {
+        beforePropertyRead("integerNullableAttribute");
+        return this.integerNullableAttribute;
+    }
+
+    public void setPkAttribute(Integer pkAttribute) {
+        beforePropertyWrite("pkAttribute", this.pkAttribute, pkAttribute);
+        this.pkAttribute = pkAttribute;
+    }
+
+    public Integer getPkAttribute() {
+        beforePropertyRead("pkAttribute");
+        return this.pkAttribute;
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "integerAttribute":
+                return this.integerAttribute;
+            case "integerNullableAttribute":
+                return this.integerNullableAttribute;
+            case "pkAttribute":
+                return this.pkAttribute;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "integerAttribute":
+                this.integerAttribute = (Integer)val;
+                break;
+            case "integerNullableAttribute":
+                this.integerNullableAttribute = (Integer)val;
+                break;
+            case "pkAttribute":
+                this.pkAttribute = (Integer)val;
+                break;
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+        out.writeObject(this.integerAttribute);
+        out.writeObject(this.integerNullableAttribute);
+        out.writeObject(this.pkAttribute);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException
{
+        super.readState(in);
+        this.integerAttribute = (Integer)in.readObject();
+        this.integerNullableAttribute = (Integer)in.readObject();
+        this.pkAttribute = (Integer)in.readObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/resources/cayenne-meaningful-pk.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cayenne-meaningful-pk.xml b/cayenne-server/src/test/resources/cayenne-meaningful-pk.xml
index feebe09..9e51cef 100644
--- a/cayenne-server/src/test/resources/cayenne-meaningful-pk.xml
+++ b/cayenne-server/src/test/resources/cayenne-meaningful-pk.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <domain xmlns="http://cayenne.apache.org/schema/10/domain"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd"
 	 project-version="10">
 	<map name="meaningful-pk"/>
+	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="meaningful-pk.graph.xml"/>
 </domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/resources/meaningful-pk.graph.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/meaningful-pk.graph.xml b/cayenne-server/src/test/resources/meaningful-pk.graph.xml
new file mode 100644
index 0000000..34d1647
--- /dev/null
+++ b/cayenne-server/src/test/resources/meaningful-pk.graph.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<graphs xmlns="http://cayenne.apache.org/schema/10/graph">
+	<graph type="ER" scale="1.0">
+		<entity name="MEANINGFUL_PK" x="318.0" y="139.0" width="115.0" height="50.0"/>
+		<entity name="MEANINGFUL_PK_TEST2" x="770.24" y="594.87" width="200.0" height="82.0"/>
+		<entity name="MEANINGFUL_PK_TEST1" x="0.0" y="155.19" width="169.0" height="98.0"/>
+		<entity name="MEANINGFUL_PK_DEP" x="276.25" y="0.0" width="148.0" height="82.0"/>
+	</graph>
+</graphs>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/cayenne-server/src/test/resources/meaningful-pk.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/meaningful-pk.map.xml b/cayenne-server/src/test/resources/meaningful-pk.map.xml
index 15e3462..a52d26e 100644
--- a/cayenne-server/src/test/resources/meaningful-pk.map.xml
+++ b/cayenne-server/src/test/resources/meaningful-pk.map.xml
@@ -16,6 +16,13 @@
 	</db-entity>
 	<db-entity name="MEANINGFUL_PK_TEST1">
 		<db-attribute name="DESCR" type="VARCHAR" length="50"/>
+		<db-attribute name="INT_ATTRIBUTE" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="INT_NULLABLE_ATTRIBUTE" type="INTEGER"/>
+		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<db-entity name="MEANINGFUL_PK_TEST2">
+		<db-attribute name="INTEGER_ATTRIBUTE" type="INTEGER" isMandatory="true"/>
+		<db-attribute name="INTEGER_NULLABLE_ATTRIBUTE" type="INTEGER"/>
 		<db-attribute name="PK_ATTRIBUTE" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
 	</db-entity>
 	<obj-entity name="MeaningfulPKDep" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKDep"
dbEntityName="MEANINGFUL_PK_DEP">
@@ -23,11 +30,18 @@
 	</obj-entity>
 	<obj-entity name="MeaningfulPKTest1" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPKTest1"
dbEntityName="MEANINGFUL_PK_TEST1">
 		<obj-attribute name="descr" type="java.lang.String" db-attribute-path="DESCR"/>
-		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
+		<obj-attribute name="intAttribute" type="int" db-attribute-path="INT_ATTRIBUTE"/>
+		<obj-attribute name="intNullableAttribute" type="int" db-attribute-path="INT_NULLABLE_ATTRIBUTE"/>
+		<obj-attribute name="pkAttribute" type="int" db-attribute-path="PK_ATTRIBUTE"/>
 	</obj-entity>
 	<obj-entity name="MeaningfulPk" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPk"
clientClassName="org.apache.cayenne.testdo.meaningful_pk.ClientMeaningfulPk" dbEntityName="MEANINGFUL_PK">
 		<obj-attribute name="pk" type="java.lang.String" db-attribute-path="PK"/>
 	</obj-entity>
+	<obj-entity name="MeaningfulPkTest2" className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkTest2"
clientClassName="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkTest2" dbEntityName="MEANINGFUL_PK_TEST2">
+		<obj-attribute name="integerAttribute" type="java.lang.Integer" db-attribute-path="INTEGER_ATTRIBUTE"/>
+		<obj-attribute name="integerNullableAttribute" type="java.lang.Integer" db-attribute-path="INTEGER_NULLABLE_ATTRIBUTE"/>
+		<obj-attribute name="pkAttribute" type="java.lang.Integer" db-attribute-path="PK_ATTRIBUTE"/>
+	</obj-entity>
 	<db-relationship name="toMeaningfulPK" source="MEANINGFUL_PK_DEP" target="MEANINGFUL_PK_TEST1">
 		<db-attribute-pair source="MASTER_PK" target="PK_ATTRIBUTE"/>
 	</db-relationship>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/74ff3fde/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 5a32f7a..4e002c4 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -20,6 +20,7 @@ Bug Fixes:
 
 CAY-2370 ValueObjectType for byte[] fails lookup
 CAY-2380 ReferenceMap should not store or return null values
+CAY-2381 cgen: meaningful PK with boxed type ends up with primitive type in generated source
 CAY-2382 Lack of synchronization in DataContext serialization
 CAY-2387 Can't select byte[] property with ColumnSelect
 CAY-2388 Modeler: Visualization issues with undo/redo actions for attributes and relationships


Mime
View raw message