You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by ab...@apache.org on 2019/06/10 13:53:12 UTC
[cayenne] 03/04: CAY-2557 Create duration extended type
This is an automated email from the ASF dual-hosted git repository.
abulatski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit c4c29ecbcba83718b2339a3ecf28cf6ad37b57b5
Author: Arseni Bulatski <an...@gmail.com>
AuthorDate: Thu May 2 13:46:06 2019 +0300
CAY-2557 Create duration extended type
---
.../apache/cayenne/access/types/DurationType.java | 139 ++++++++++++++++++
.../cayenne/access/types/DurationValueType.java | 53 -------
.../cayenne/configuration/server/ServerModule.java | 8 +-
.../apache/cayenne/access/types/Java8TimeIT.java | 43 +++++-
.../testdo/java8/auto/_DurationTestEntity.java | 161 +++++++++++++++++++--
.../cayenne/unit/di/server/ServerCaseModule.java | 6 +-
cayenne-server/src/test/resources/java8.map.xml | 18 ++-
.../org/apache/cayenne/modeler/Application.java | 16 +-
8 files changed, 357 insertions(+), 87 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationType.java
new file mode 100644
index 0000000..ab2da3c
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationType.java
@@ -0,0 +1,139 @@
+package org.apache.cayenne.access.types;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Types;
+import java.time.Duration;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.dba.TypesMapping;
+
+public class DurationType implements ExtendedType<Duration> {
+
+ @Override
+ public String getClassName() {
+ return Duration.class.getName();
+ }
+
+ protected Object convertToJdbcObject(Duration val, int type) {
+ if(type == Types.INTEGER) {
+ return new Long(val.toMillis()).intValue();
+ } else if(type == Types.NUMERIC) {
+ return val.toMillis();
+ } else if(type == Types.DECIMAL) {
+ return val.toMillis();
+ } else if (type == Types.BIGINT) {
+ return val.toMillis();
+ } else if (type == Types.VARCHAR) {
+ return val.toString();
+ } else if(type == Types.LONGVARCHAR) {
+ return val.toString();
+ } else if(type == Types.NVARCHAR) {
+ return val.toString();
+ } else if(type == Types.LONGNVARCHAR) {
+ return val.toString();
+ } else {
+ throw new IllegalArgumentException(
+ "Only INTEGER, NUMERIC, DECIMAL, BIGINT, VARCHAR, LONGVARCHAR, NVARCHAR, LONGNVARCHAR " +
+ "can be mapped as '" + getClassName()
+ + "', got " + TypesMapping.getSqlNameByType(type));
+ }
+ }
+
+ @Override
+ public void setJdbcObject(PreparedStatement statement, Duration value, int pos, int type, int scale) throws Exception {
+ if(value == null) {
+ statement.setNull(pos, type);
+ } else {
+ statement.setObject(pos, convertToJdbcObject(value, type), type);
+ }
+ }
+
+ @Override
+ public Duration materializeObject(ResultSet rs, int index, int type) throws Exception {
+ Duration val = null;
+ switch(type) {
+ case Types.INTEGER:
+ val = Duration.ofMillis(rs.getInt(index));
+ break;
+ case Types.NUMERIC:
+ val = Duration.ofMillis(rs.getBigDecimal(index).longValue());
+ break;
+ case Types.DECIMAL:
+ val = Duration.ofMillis(rs.getBigDecimal(index).longValue());
+ break;
+ case Types.BIGINT:
+ val = Duration.ofMillis(rs.getLong(index));
+ break;
+ case Types.VARCHAR:
+ val = Duration.parse(rs.getString(index));
+ break;
+ case Types.LONGVARCHAR:
+ val = Duration.parse(rs.getString(index));
+ break;
+ case Types.NVARCHAR:
+ val = Duration.parse(rs.getNString(index));
+ break;
+ case Types.LONGNVARCHAR:
+ val = Duration.parse(rs.getNString(index));
+ break;
+ }
+
+ if(rs.wasNull()) {
+ return null;
+ } else if(val != null) {
+ return val;
+ } else {
+ throw new CayenneRuntimeException("Can't materialize " + rs.getObject(index) + " of type: " + type);
+ }
+ }
+
+ @Override
+ public Duration materializeObject(CallableStatement rs, int index, int type) throws Exception {
+ Duration val = null;
+ switch(type) {
+ case Types.INTEGER:
+ val = Duration.ofMillis(rs.getInt(index));
+ break;
+ case Types.NUMERIC:
+ val = Duration.ofMillis(rs.getBigDecimal(index).longValue());
+ break;
+ case Types.DECIMAL:
+ val = Duration.ofMillis(rs.getBigDecimal(index).longValue());
+ break;
+ case Types.BIGINT:
+ val = Duration.ofMillis(rs.getLong(index));
+ break;
+ case Types.VARCHAR:
+ val = Duration.parse(rs.getString(index));
+ break;
+ case Types.LONGVARCHAR:
+ val = Duration.parse(rs.getString(index));
+ break;
+ case Types.NVARCHAR:
+ val = Duration.parse(rs.getNString(index));
+ break;
+ case Types.LONGNVARCHAR:
+ val = Duration.parse(rs.getNString(index));
+ break;
+ }
+
+ if(rs.wasNull()) {
+ return null;
+ } else if(val != null) {
+ return val;
+ } else {
+ throw new CayenneRuntimeException("Can't materialize " + rs.getObject(index) + " of type: " + type);
+ }
+ }
+
+ @Override
+ public String toString(Duration value) {
+ if(value == null) {
+ return "NULL";
+ }
+
+ return "\'" + value.toString() + "\'";
+ }
+}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationValueType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationValueType.java
deleted file mode 100644
index 1d2b0f4..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DurationValueType.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*****************************************************************
- * 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;
-
-import java.time.Duration;
-
-/**
- * @since 4.2
- */
-public class DurationValueType implements ValueObjectType<Duration, String> {
-
- @Override
- public Class<String> getTargetType() {
- return String.class;
- }
-
- @Override
- public Class<Duration> getValueType() {
- return Duration.class;
- }
-
- @Override
- public Duration toJavaObject(String value) {
- return Duration.parse(value);
- }
-
- @Override
- public String fromJavaObject(Duration object) {
- return object.toString();
- }
-
- @Override
- public String toCacheKey(Duration object) {
- return object.toString();
- }
-}
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 92fadaa..5c14a21 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
@@ -50,7 +50,7 @@ import org.apache.cayenne.access.types.CharacterValueType;
import org.apache.cayenne.access.types.DateType;
import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry;
import org.apache.cayenne.access.types.DoubleType;
-import org.apache.cayenne.access.types.DurationValueType;
+import org.apache.cayenne.access.types.DurationType;
import org.apache.cayenne.access.types.ExtendedType;
import org.apache.cayenne.access.types.ExtendedTypeFactory;
import org.apache.cayenne.access.types.FloatType;
@@ -413,8 +413,11 @@ public class ServerModule implements Module {
.add(new DateType())
.add(new TimeType())
.add(new TimestampType())
+ .add(new DurationType())
// should be converted from ExtendedType to ValueType
- .add(new UtilDateType()).add(new CalendarType<>(GregorianCalendar.class)).add(new CalendarType<>(Calendar.class));
+ .add(new UtilDateType())
+ .add(new CalendarType<>(GregorianCalendar.class))
+ .add(new CalendarType<>(Calendar.class));
contributeUserTypes(binder);
contributeTypeFactories(binder);
@@ -425,7 +428,6 @@ public class ServerModule implements Module {
.add(LocalDateValueType.class)
.add(LocalTimeValueType.class)
.add(LocalDateTimeValueType.class)
- .add(DurationValueType.class)
.add(PeriodValueType.class)
.add(CharacterValueType.class);
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/types/Java8TimeIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/types/Java8TimeIT.java
index 632b2be..2c51576 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/types/Java8TimeIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/types/Java8TimeIT.java
@@ -151,15 +151,50 @@ public class Java8TimeIT extends ServerCase {
public void testJava8Duration() {
DurationTestEntity durationTestEntity = context.newObject(DurationTestEntity.class);
Duration duration = Duration.ofDays(10);
- durationTestEntity.setDurationField(duration);
+ durationTestEntity.setDurationBigInt(duration);
+ durationTestEntity.setDurationDecimal(duration);
+ durationTestEntity.setDurationInt(duration);
+ durationTestEntity.setDurationLongNVarchar(duration);
+ durationTestEntity.setDurationLongVarchar(duration);
+ durationTestEntity.setDurationNumeric(duration);
+ durationTestEntity.setDurationVarchar(duration);
+ durationTestEntity.setDurationNVarchar(duration);
context.commitChanges();
DurationTestEntity testRead = ObjectSelect.query(DurationTestEntity.class).selectOne(context);
- assertNotNull(testRead.getDurationField());
- assertEquals(Duration.class, testRead.getDurationField().getClass());
- assertEquals(duration, testRead.getDurationField());
+ assertNotNull(testRead.getDurationBigInt());
+ assertEquals(Duration.class, testRead.getDurationBigInt().getClass());
+ assertEquals(duration, testRead.getDurationBigInt());
+
+ assertNotNull(testRead.getDurationDecimal());
+ assertEquals(Duration.class, testRead.getDurationDecimal().getClass());
+ assertEquals(duration, testRead.getDurationDecimal());
+
+ assertNotNull(testRead.getDurationInt());
+ assertEquals(Duration.class, testRead.getDurationInt().getClass());
+ assertEquals(duration, testRead.getDurationInt());
+
+ assertNotNull(testRead.getDurationLongNVarchar());
+ assertEquals(Duration.class, testRead.getDurationLongNVarchar().getClass());
+ assertEquals(duration, testRead.getDurationLongNVarchar());
+
+ assertNotNull(testRead.getDurationLongVarchar());
+ assertEquals(Duration.class, testRead.getDurationLongVarchar().getClass());
+ assertEquals(duration, testRead.getDurationLongVarchar());
+
+ assertNotNull(testRead.getDurationNumeric());
+ assertEquals(Duration.class, testRead.getDurationNumeric().getClass());
+ assertEquals(duration, testRead.getDurationNumeric());
+
+ assertNotNull(testRead.getDurationVarchar());
+ assertEquals(Duration.class, testRead.getDurationVarchar().getClass());
+ assertEquals(duration, testRead.getDurationVarchar());
+
+ assertNotNull(testRead.getDurationNVarchar());
+ assertEquals(Duration.class, testRead.getDurationNVarchar().getClass());
+ assertEquals(duration, testRead.getDurationNVarchar());
}
@Test
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/testdo/java8/auto/_DurationTestEntity.java b/cayenne-server/src/test/java/org/apache/cayenne/testdo/java8/auto/_DurationTestEntity.java
index d0b1fd0..3b9d018 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/testdo/java8/auto/_DurationTestEntity.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/java8/auto/_DurationTestEntity.java
@@ -21,19 +21,103 @@ public abstract class _DurationTestEntity extends BaseDataObject {
public static final String ID_PK_COLUMN = "ID";
- public static final BaseProperty<Duration> DURATION_FIELD = PropertyFactory.createBase("durationField", Duration.class);
+ public static final BaseProperty<Duration> DURATION_VARCHAR = PropertyFactory.createBase("durationVarchar", Duration.class);
+ public static final BaseProperty<Duration> DURATION_BIG_INT = PropertyFactory.createBase("durationBigInt", Duration.class);
+ public static final BaseProperty<Duration> DURATION_NUMERIC = PropertyFactory.createBase("durationNumeric", Duration.class);
+ public static final BaseProperty<Duration> DURATION_DECIMAL = PropertyFactory.createBase("durationDecimal", Duration.class);
+ public static final BaseProperty<Duration> DURATION_LONG_VARCHAR = PropertyFactory.createBase("durationLongVarchar", Duration.class);
+ public static final BaseProperty<Duration> DURATION_NVARCHAR = PropertyFactory.createBase("durationNVarchar", Duration.class);
+ public static final BaseProperty<Duration> DURATION_LONG_NVARCHAR = PropertyFactory.createBase("durationLongNVarchar", Duration.class);
+ public static final BaseProperty<Duration> DURATION_INT = PropertyFactory.createBase("durationInt", Duration.class);
+
+ protected Duration durationVarchar;
+ protected Duration durationBigInt;
+ protected Duration durationNumeric;
+ protected Duration durationDecimal;
+ protected Duration durationLongVarchar;
+ protected Duration durationNVarchar;
+ protected Duration durationLongNVarchar;
+ protected Duration durationInt;
+
+
+ public void setDurationVarchar(Duration durationVarchar) {
+ beforePropertyWrite("durationVarchar", this.durationVarchar, durationVarchar);
+ this.durationVarchar = durationVarchar;
+ }
+
+ public Duration getDurationVarchar() {
+ beforePropertyRead("durationVarchar");
+ return this.durationVarchar;
+ }
+
+ public void setDurationBigInt(Duration durationBigInt) {
+ beforePropertyWrite("durationBigInt", this.durationBigInt, durationBigInt);
+ this.durationBigInt = durationBigInt;
+ }
+
+ public Duration getDurationBigInt() {
+ beforePropertyRead("durationBigInt");
+ return this.durationBigInt;
+ }
+
+ public void setDurationNumeric(Duration durationNumeric) {
+ beforePropertyWrite("durationNumeric", this.durationNumeric, durationNumeric);
+ this.durationNumeric = durationNumeric;
+ }
+
+ public Duration getDurationNumeric() {
+ beforePropertyRead("durationNumeric");
+ return this.durationNumeric;
+ }
+
+ public void setDurationDecimal(Duration durationDecimal) {
+ beforePropertyWrite("durationDecimal", this.durationDecimal, durationDecimal);
+ this.durationDecimal = durationDecimal;
+ }
+
+ public Duration getDurationDecimal() {
+ beforePropertyRead("durationDecimal");
+ return this.durationDecimal;
+ }
+
+ public void setDurationLongVarchar(Duration durationLongVarchar) {
+ beforePropertyWrite("durationLongVarchar", this.durationLongVarchar, durationLongVarchar);
+ this.durationLongVarchar = durationLongVarchar;
+ }
+
+ public Duration getDurationLongVarchar() {
+ beforePropertyRead("durationLongVarchar");
+ return this.durationLongVarchar;
+ }
+
+ public void setDurationNVarchar(Duration durationNVarchar) {
+ beforePropertyWrite("durationNVarchar", this.durationNVarchar, durationNVarchar);
+ this.durationNVarchar = durationNVarchar;
+ }
+
+ public Duration getDurationNVarchar() {
+ beforePropertyRead("durationNVarchar");
+ return this.durationNVarchar;
+ }
- protected Duration durationField;
+ public void setDurationLongNVarchar(Duration durationLongNVarchar) {
+ beforePropertyWrite("durationLongNVarchar", this.durationLongNVarchar, durationLongNVarchar);
+ this.durationLongNVarchar = durationLongNVarchar;
+ }
+ public Duration getDurationLongNVarchar() {
+ beforePropertyRead("durationLongNVarchar");
+ return this.durationLongNVarchar;
+ }
- public void setDurationField(Duration durationField) {
- beforePropertyWrite("durationField", this.durationField, durationField);
- this.durationField = durationField;
+ public void setDurationInt(Duration durationInt) {
+ beforePropertyWrite("durationInt", this.durationInt, durationInt);
+ this.durationInt = durationInt;
}
- public Duration getDurationField() {
- beforePropertyRead("durationField");
- return this.durationField;
+ public Duration getDurationInt() {
+ beforePropertyRead("durationInt");
+ return this.durationInt;
}
@Override
@@ -43,8 +127,22 @@ public abstract class _DurationTestEntity extends BaseDataObject {
}
switch(propName) {
- case "durationField":
- return this.durationField;
+ case "durationVarchar":
+ return this.durationVarchar;
+ case "durationBigInt":
+ return this.durationBigInt;
+ case "durationNumeric":
+ return this.durationNumeric;
+ case "durationDecimal":
+ return this.durationDecimal;
+ case "durationLongVarchar":
+ return this.durationLongVarchar;
+ case "durationNVarchar":
+ return this.durationNVarchar;
+ case "durationLongNVarchar":
+ return this.durationLongNVarchar;
+ case "durationInt":
+ return this.durationInt;
default:
return super.readPropertyDirectly(propName);
}
@@ -57,8 +155,29 @@ public abstract class _DurationTestEntity extends BaseDataObject {
}
switch (propName) {
- case "durationField":
- this.durationField = (Duration)val;
+ case "durationVarchar":
+ this.durationVarchar = (Duration)val;
+ break;
+ case "durationBigInt":
+ this.durationBigInt = (Duration)val;
+ break;
+ case "durationNumeric":
+ this.durationNumeric = (Duration)val;
+ break;
+ case "durationDecimal":
+ this.durationDecimal = (Duration)val;
+ break;
+ case "durationLongVarchar":
+ this.durationLongVarchar = (Duration)val;
+ break;
+ case "durationNVarchar":
+ this.durationNVarchar = (Duration)val;
+ break;
+ case "durationLongNVarchar":
+ this.durationLongNVarchar = (Duration)val;
+ break;
+ case "durationInt":
+ this.durationInt = (Duration)val;
break;
default:
super.writePropertyDirectly(propName, val);
@@ -76,13 +195,27 @@ public abstract class _DurationTestEntity extends BaseDataObject {
@Override
protected void writeState(ObjectOutputStream out) throws IOException {
super.writeState(out);
- out.writeObject(this.durationField);
+ out.writeObject(this.durationVarchar);
+ out.writeObject(this.durationBigInt);
+ out.writeObject(this.durationNumeric);
+ out.writeObject(this.durationDecimal);
+ out.writeObject(this.durationLongVarchar);
+ out.writeObject(this.durationNVarchar);
+ out.writeObject(this.durationLongNVarchar);
+ out.writeObject(this.durationInt);
}
@Override
protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
super.readState(in);
- this.durationField = (Duration)in.readObject();
+ this.durationVarchar = (Duration)in.readObject();
+ this.durationBigInt = (Duration)in.readObject();
+ this.durationNumeric = (Duration)in.readObject();
+ this.durationDecimal = (Duration)in.readObject();
+ this.durationLongVarchar = (Duration)in.readObject();
+ this.durationNVarchar = (Duration)in.readObject();
+ this.durationLongNVarchar = (Duration)in.readObject();
+ this.durationInt = (Duration)in.readObject();
}
}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
index 2080b0b..674ebda 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java
@@ -38,7 +38,7 @@ import org.apache.cayenne.access.types.CharacterValueType;
import org.apache.cayenne.access.types.DateType;
import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry;
import org.apache.cayenne.access.types.DoubleType;
-import org.apache.cayenne.access.types.DurationValueType;
+import org.apache.cayenne.access.types.DurationType;
import org.apache.cayenne.access.types.FloatType;
import org.apache.cayenne.access.types.IntegerType;
import org.apache.cayenne.access.types.LocalDateTimeValueType;
@@ -210,7 +210,8 @@ public class ServerCaseModule implements Module {
.add(new TimestampType())
.add(new UtilDateType())
.add(new CalendarType<>(GregorianCalendar.class))
- .add(new CalendarType<>(Calendar.class));
+ .add(new CalendarType<>(Calendar.class))
+ .add(new DurationType());
ServerModule.contributeUserTypes(binder);
ServerModule.contributeTypeFactories(binder);
ServerModule.contributeValueObjectTypes(binder)
@@ -219,7 +220,6 @@ public class ServerCaseModule implements Module {
.add(LocalDateValueType.class)
.add(LocalTimeValueType.class)
.add(LocalDateTimeValueType.class)
- .add(DurationValueType.class)
.add(PeriodValueType.class)
.add(CharacterValueType.class);
binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class);
diff --git a/cayenne-server/src/test/resources/java8.map.xml b/cayenne-server/src/test/resources/java8.map.xml
index f96f7ef..692cc77 100644
--- a/cayenne-server/src/test/resources/java8.map.xml
+++ b/cayenne-server/src/test/resources/java8.map.xml
@@ -5,7 +5,14 @@
project-version="10">
<property name="defaultPackage" value="org.apache.cayenne.testdo.java8"/>
<db-entity name="DURATION_TEST">
- <db-attribute name="DurationField" type="VARCHAR" length="100"/>
+ <db-attribute name="DurationBigInt" type="BIGINT"/>
+ <db-attribute name="DurationDecimal" type="DECIMAL"/>
+ <db-attribute name="DurationInt" type="INTEGER" length="100"/>
+ <db-attribute name="DurationLongNVarchar" type="LONGNVARCHAR" length="100"/>
+ <db-attribute name="DurationLongVarchar" type="LONGVARCHAR" length="100"/>
+ <db-attribute name="DurationNVarchar" type="NVARCHAR" length="100"/>
+ <db-attribute name="DurationNumeric" type="NUMERIC"/>
+ <db-attribute name="DurationVarchar" type="VARCHAR" length="100"/>
<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
</db-entity>
<db-entity name="LOCAL_DATETIME_TEST">
@@ -25,7 +32,14 @@
<db-attribute name="PeriodField" type="VARCHAR" length="100"/>
</db-entity>
<obj-entity name="DurationTest" className="org.apache.cayenne.testdo.java8.DurationTestEntity" dbEntityName="DURATION_TEST">
- <obj-attribute name="durationField" type="java.time.Duration" db-attribute-path="DurationField"/>
+ <obj-attribute name="durationVarchar" type="java.time.Duration" db-attribute-path="DurationVarchar"/>
+ <obj-attribute name="durationBigInt" type="java.time.Duration" db-attribute-path="DurationBigInt"/>
+ <obj-attribute name="durationNumeric" type="java.time.Duration" db-attribute-path="DurationNumeric"/>
+ <obj-attribute name="durationDecimal" type="java.time.Duration" db-attribute-path="DurationDecimal"/>
+ <obj-attribute name="durationLongVarchar" type="java.time.Duration" db-attribute-path="DurationLongVarchar"/>
+ <obj-attribute name="durationNVarchar" type="java.time.Duration" db-attribute-path="DurationNVarchar"/>
+ <obj-attribute name="durationLongNVarchar" type="java.time.Duration" db-attribute-path="DurationLongNVarchar"/>
+ <obj-attribute name="durationInt" type="java.time.Duration" db-attribute-path="DurationInt"/>
</obj-entity>
<obj-entity name="LocalDateTest" className="org.apache.cayenne.testdo.java8.LocalDateTestEntity" dbEntityName="LOCAL_DATE_TEST">
<obj-attribute name="date" type="java.time.LocalDate" db-attribute-path="DateField"/>
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
index 8bd18b4..a4e2810 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
@@ -19,6 +19,14 @@
package org.apache.cayenne.modeler;
+import javax.swing.*;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
+
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.di.Inject;
@@ -35,14 +43,6 @@ import org.apache.cayenne.project.Project;
import org.apache.cayenne.swing.BindingFactory;
import org.apache.cayenne.util.IDUtil;
-import javax.swing.*;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.prefs.BackingStoreException;
-import java.util.prefs.Preferences;
-import java.util.stream.Collectors;
-
/**
* A main modeler application class that provides a number of services to the Modeler
* components. Configuration properties: