Repository: cayenne Updated Branches: refs/heads/STABLE-4.0 1b945ae6c -> 53fc0ae3e
CAY-2367 ClassCastException reading an attribute of type 'char' Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/53fc0ae3 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/53fc0ae3 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/53fc0ae3 Branch: refs/heads/STABLE-4.0 Commit: 53fc0ae3ebedc0d6af0364064c565687986ed742 Parents: 1b945ae Author: Nikita Timofeev <stari...@gmail.com> Authored: Tue Oct 3 11:40:12 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Tue Oct 3 11:40:12 2017 +0300 ---------------------------------------------------------------------- .../cayenne/access/types/CharacterType.java | 60 ++++++++++++++++++++ .../cayenne/access/types/ExtendedTypeMap.java | 1 + .../configuration/server/ServerModule.java | 4 +- .../cayenne/access/PrimitiveAttributesIT.java | 37 ++++++++++++ .../primitive/auto/_PrimitivesTestEntity.java | 9 +++ .../src/test/resources/primitive.map.xml | 2 + docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + 7 files changed, 113 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/main/java/org/apache/cayenne/access/types/CharacterType.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/CharacterType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/CharacterType.java new file mode 100644 index 0000000..dcc1c98 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/CharacterType.java @@ -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.access.types; + +/** + * This is char and Character type mapped to zero or one char String. + * @since 4.0 + */ +public class CharacterType implements ValueObjectType<Character, String> { + @Override + public Class<String> getTargetType() { + return String.class; + } + + @Override + public Class<Character> getValueType() { + return Character.class; + } + + @Override + public Character toJavaObject(String value) { + if(value == null) { + return null; + } + if(value.isEmpty()) { + return 0; + } + if(value.length() > 1) { + throw new IllegalArgumentException("Only one char String can be used, " + value + " used"); + } + return value.charAt(0); + } + + @Override + public String fromJavaObject(Character object) { + return String.valueOf(object); + } + + @Override + public String toCacheKey(Character object) { + return String.valueOf(object); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java index de620ec..8d3d31b 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java @@ -47,6 +47,7 @@ public class ExtendedTypeMap { classesForPrimitives.put("float", Float.class.getName()); classesForPrimitives.put("short", Short.class.getName()); classesForPrimitives.put("int", Integer.class.getName()); + classesForPrimitives.put("char", Character.class.getName()); } protected Map<String, String> typeAliases; http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java index 962bba9..723a24b 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java @@ -41,6 +41,7 @@ import org.apache.cayenne.access.types.ByteArrayType; import org.apache.cayenne.access.types.ByteType; import org.apache.cayenne.access.types.CalendarType; import org.apache.cayenne.access.types.CharType; +import org.apache.cayenne.access.types.CharacterType; import org.apache.cayenne.access.types.DateType; import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; import org.apache.cayenne.access.types.DoubleType; @@ -328,7 +329,8 @@ public class ServerModule implements Module { // Custom ValueObjects types contribution contributeValueObjectTypes(binder) .add(BigIntegerValueType.class) - .add(UUIDValueType.class); + .add(UUIDValueType.class) + .add(CharacterType.class); binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); // configure explicit configurations http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/test/java/org/apache/cayenne/access/PrimitiveAttributesIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/PrimitiveAttributesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/PrimitiveAttributesIT.java index 5fa1907..c9f2d5b 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/PrimitiveAttributesIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/PrimitiveAttributesIT.java @@ -18,24 +18,61 @@ ****************************************************************/ package org.apache.cayenne.access; +import java.util.List; + import org.apache.cayenne.di.Inject; +import org.apache.cayenne.query.ObjectSelect; +import org.apache.cayenne.test.jdbc.DBHelper; +import org.apache.cayenne.test.jdbc.TableHelper; import org.apache.cayenne.testdo.primitive.PrimitivesTestEntity; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + @UseServerRuntime(CayenneProjects.PRIMITIVE_PROJECT) public class PrimitiveAttributesIT extends ServerCase { @Inject private DataContext context; + @Inject + private DBHelper dbHelper; + @Test public void testCommit() { PrimitivesTestEntity e = context.newObject(PrimitivesTestEntity.class); e.setBooleanColumn(true); + e.setCharColumn('B'); e.setIntColumn(88); context.commitChanges(); } + + @Test + public void testSelect() throws Exception { + TableHelper tPrimitives = new TableHelper(dbHelper, "PRIMITIVES_TEST"); + tPrimitives.setColumns("ID", "BOOLEAN_COLUMN", "INT_COLUMN", "CHAR_COLUMN"); + tPrimitives.insert(1, true, -100, String.valueOf('a')) + .insert(2, false, 0, String.valueOf('~')) + .insert(3, true, Integer.MAX_VALUE, String.valueOf('Ã ')); + + List<PrimitivesTestEntity> result = ObjectSelect.query(PrimitivesTestEntity.class) + .orderBy(PrimitivesTestEntity.INT_COLUMN.asc()).select(context); + assertEquals(3, result.size()); + assertEquals(-100, result.get(0).getIntColumn()); + assertEquals('a', result.get(0).getCharColumn()); + assertTrue(result.get(0).isBooleanColumn()); + + assertEquals(0, result.get(1).getIntColumn()); + assertEquals('~', result.get(1).getCharColumn()); + assertFalse(result.get(1).isBooleanColumn()); + + assertEquals(Integer.MAX_VALUE, result.get(2).getIntColumn()); + assertEquals('Ã ', result.get(2).getCharColumn()); + assertTrue(result.get(2).isBooleanColumn()); + } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java index 66edc80..16c8c6a 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/primitive/auto/_PrimitivesTestEntity.java @@ -16,6 +16,7 @@ public abstract class _PrimitivesTestEntity extends CayenneDataObject { public static final String ID_PK_COLUMN = "ID"; public static final Property<Boolean> BOOLEAN_COLUMN = Property.create("booleanColumn", Boolean.class); + public static final Property<Character> CHAR_COLUMN = Property.create("charColumn", Character.class); public static final Property<Integer> INT_COLUMN = Property.create("intColumn", Integer.class); public void setBooleanColumn(boolean booleanColumn) { @@ -26,6 +27,14 @@ public abstract class _PrimitivesTestEntity extends CayenneDataObject { return (value != null) ? value.booleanValue() : false; } + public void setCharColumn(char charColumn) { + writeProperty("charColumn", charColumn); + } + public char getCharColumn() { + Object value = readProperty("charColumn"); + return (value != null) ? (Character) value : 0; + } + public void setIntColumn(int intColumn) { writeProperty("intColumn", intColumn); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/cayenne-server/src/test/resources/primitive.map.xml ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/resources/primitive.map.xml b/cayenne-server/src/test/resources/primitive.map.xml index d5e83dc..f780704 100644 --- a/cayenne-server/src/test/resources/primitive.map.xml +++ b/cayenne-server/src/test/resources/primitive.map.xml @@ -10,11 +10,13 @@ <property name="defaultClientSuperclass" value="org.apache.cayenne.PersistentObject"/> <db-entity name="PRIMITIVES_TEST"> <db-attribute name="BOOLEAN_COLUMN" type="BOOLEAN"/> + <db-attribute name="CHAR_COLUMN" type="CHAR" length="1"/> <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/> <db-attribute name="INT_COLUMN" type="INTEGER"/> </db-entity> <obj-entity name="PrimitivesTestEntity" className="org.apache.cayenne.testdo.primitive.PrimitivesTestEntity" dbEntityName="PRIMITIVES_TEST"> <obj-attribute name="booleanColumn" type="boolean" db-attribute-path="BOOLEAN_COLUMN"/> + <obj-attribute name="charColumn" type="char" db-attribute-path="CHAR_COLUMN"/> <obj-attribute name="intColumn" type="int" db-attribute-path="INT_COLUMN"/> </obj-entity> </data-map> http://git-wip-us.apache.org/repos/asf/cayenne/blob/53fc0ae3/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 7aa154b..126abdb 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -15,6 +15,7 @@ Bug Fixes: CAY-2364 Wrong logging in SQLTemplate CAY-2365 SQLExec query tries to convert (unexpected) result set into objects +CAY-2367 ClassCastException reading object with an attribute of type 'char' CAY-2368 ColumnSelect: Property.self() translates into wrong SQL code ----------------------------------