Repository: cayenne Updated Branches: refs/heads/master b34c76b24 -> 0c9098138
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/0c909813 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0c909813 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0c909813 Branch: refs/heads/master Commit: 0c9098138cae58eb1f6c52554ac8002d1ea1aadb Parents: b34c76b Author: Nikita Timofeev <stari...@gmail.com> Authored: Tue Sep 26 17:52:21 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Tue Sep 26 17:52:21 2017 +0300 ---------------------------------------------------------------------- .../cayenne/access/types/CharacterType.java | 60 ++++++++++++++++++++ .../cayenne/access/types/ExtendedTypeMap.java | 1 + .../configuration/server/ServerModule.java | 4 +- .../cayenne/access/PrimitiveAttributesIT.java | 30 ++++++++++ .../primitive/auto/_PrimitivesTestEntity.java | 17 ++++++ .../src/test/resources/primitive.map.xml | 2 + docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + 7 files changed, 114 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c909813/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..adc360e --- /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.1 + */ +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/0c909813/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/0c909813/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 bc2e879..cf934a6 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 @@ -40,6 +40,7 @@ import org.apache.cayenne.access.types.BooleanType; 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.CharacterType; import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.DateType; import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; @@ -342,7 +343,8 @@ public class ServerModule implements Module { .add(UUIDValueType.class) .add(LocalDateValueType.class) .add(LocalTimeValueType.class) - .add(LocalDateTimeValueType.class); + .add(LocalDateTimeValueType.class) + .add(CharacterType.class); binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c909813/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..521a1de 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,54 @@ ****************************************************************/ 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.UnitDbAdapter; 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; + @UseServerRuntime(CayenneProjects.PRIMITIVE_PROJECT) public class PrimitiveAttributesIT extends ServerCase { @Inject private DataContext context; + @Inject + private DBHelper dbHelper; + + @Inject + private UnitDbAdapter unitDbAdapter; + @Test public void testCommit() { PrimitivesTestEntity e = context.newObject(PrimitivesTestEntity.class); e.setBooleanColumn(true); e.setIntColumn(88); + e.setCharColumn('B'); context.commitChanges(); } + + @Test + public void testSelect() throws Exception { + TableHelper tPrimitives = new TableHelper(dbHelper, "PRIMITIVES_TEST"); + tPrimitives.setColumns("ID", "BOOLEAN_COLUMN", "INT_COLUMN", "CHAR_COLUMN"); + for (int i = 1; i <= 20; i++) { + tPrimitives.insert(i, (i % 2 == 0), i * 10, (char) ('a' + i)); + } + + List<PrimitivesTestEntity> result = ObjectSelect.query(PrimitivesTestEntity.class) + .orderBy(PrimitivesTestEntity.INT_COLUMN.asc()).select(context); + assertEquals(20, result.size()); + assertEquals(40, result.get(3).getIntColumn()); + assertEquals('d', result.get(2).getCharColumn()); + } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c909813/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 640f660..6750a4f 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 @@ -20,9 +20,11 @@ public abstract class _PrimitivesTestEntity extends BaseDataObject { 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); protected boolean booleanColumn; + protected char charColumn; protected int intColumn; @@ -36,6 +38,16 @@ public abstract class _PrimitivesTestEntity extends BaseDataObject { return this.booleanColumn; } + public void setCharColumn(char charColumn) { + beforePropertyWrite("charColumn", this.charColumn, charColumn); + this.charColumn = charColumn; + } + + public char getCharColumn() { + beforePropertyRead("charColumn"); + return this.charColumn; + } + public void setIntColumn(int intColumn) { beforePropertyWrite("intColumn", this.intColumn, intColumn); this.intColumn = intColumn; @@ -55,6 +67,8 @@ public abstract class _PrimitivesTestEntity extends BaseDataObject { switch(propName) { case "booleanColumn": return this.booleanColumn; + case "charColumn": + return this.charColumn; case "intColumn": return this.intColumn; default: @@ -72,6 +86,9 @@ public abstract class _PrimitivesTestEntity extends BaseDataObject { case "booleanColumn": this.booleanColumn = val == null ? false : (Boolean)val; break; + case "charColumn": + this.charColumn = val == null ? 0 : (Character)val; + break; case "intColumn": this.intColumn = val == null ? 0 : (Integer)val; break; http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c909813/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 8173637..965b717 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/0c909813/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 e8400e4..d330e5f 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -45,6 +45,7 @@ CAY-2363 ColumnSelect: unable to use from nested context CAY-2364 Wrong logging in SQLTemplate CAY-2365 SQLExec query tries to convert (unexpected) result set into objects CAY-2366 Incorrect EJBQL COUNT translation +CAY-2367 ClassCastException reading object with an attribute of type 'char' CAY-2368 ColumnSelect: Property.self() translates into wrong SQL code ----------------------------------