diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/DeployCreateProperties.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/DeployCreateProperties.java index a6b277e85..ad5674de4 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/DeployCreateProperties.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/DeployCreateProperties.java @@ -152,7 +152,7 @@ public class DeployCreateProperties { Class superClass = beanType.getSuperclass(); if (!superClass.equals(Object.class)) { - // recursively add any properties in the inheritance heirarchy + // recursively add any properties in the inheritance hierarchy // up to the Object.class level... createProperties(desc, superClass, level + 1); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseDate.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseDate.java index 8f39b6cfd..8cc4de223 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseDate.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeBaseDate.java @@ -39,19 +39,14 @@ public abstract class ScalarTypeBaseDate extends ScalarTypeBase { if (value == null) { b.setNull(Types.DATE); } else { - Date date = convertToDate(value); - b.setDate(date); + b.setDate(convertToDate(value)); } } public T read(DataReader dataReader) throws SQLException { Date ts = dataReader.getDate(); - if (ts == null) { - return null; - } else { - return convertFromDate(ts); - } + return ts == null ? null : convertFromDate(ts); } public String formatValue(T t) { diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDuration.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDuration.java index 23cbbcd42..4439b15a9 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDuration.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDuration.java @@ -9,10 +9,10 @@ import com.fasterxml.jackson.core.JsonToken; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.math.BigDecimal; import java.sql.SQLException; import java.sql.Types; import java.time.Duration; -import java.time.LocalTime; /** * ScalarType for java.time.Duration @@ -27,6 +27,14 @@ public class ScalarTypeDuration extends ScalarTypeBase { super(Duration.class, false, jdbcType); } + public BigDecimal convertToBigDecimal(Duration value) { + return (value == null) ? null : DecimalUtils.toDecimal(value); + } + + public Duration convertFromBigDecimal(BigDecimal value) { + return (value == null) ? null : DecimalUtils.toDuration(value); + } + @Override public void bind(DataBind bind, Duration value) throws SQLException { if (value == null) { @@ -38,26 +46,8 @@ public class ScalarTypeDuration extends ScalarTypeBase { @Override public Duration read(DataReader dataReader) throws SQLException { - return Duration.ofSeconds(dataReader.getLong()); - } - - @Override - public Duration readData(DataInput dataInput) throws IOException { - if (!dataInput.readBoolean()) { - return null; - } else { - return Duration.ofSeconds(dataInput.readLong()); - } - } - - @Override - public void writeData(DataOutput dataOutput, Duration value) throws IOException { - if (value == null) { - dataOutput.writeBoolean(false); - } else { - dataOutput.writeBoolean(true); - dataOutput.writeLong(value.getSeconds()); - } + Long value = dataReader.getLong(); + return (value == null) ? null : Duration.ofSeconds(value); } @Override @@ -72,6 +62,26 @@ public class ScalarTypeDuration extends ScalarTypeBase { return Duration.ofSeconds(BasicTypeConverter.toLong(value)); } + @Override + public Duration readData(DataInput dataInput) throws IOException { + if (!dataInput.readBoolean()) { + return null; + } else { + return convertFromBigDecimal(new BigDecimal(dataInput.readUTF())); + } + } + + @Override + public void writeData(DataOutput dataOutput, Duration value) throws IOException { + if (value == null) { + dataOutput.writeBoolean(false); + } else { + dataOutput.writeBoolean(true); + dataOutput.writeUTF(convertToBigDecimal(value).toString()); + } + } + + @Override public String formatValue(Duration v) { return v.toString(); diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java index 78d792614..ab0f8065a 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java @@ -26,14 +26,6 @@ public class ScalarTypeDurationWithNanos extends ScalarTypeDuration { super(Types.DECIMAL); } - public BigDecimal convertToBigDecimal(Duration value) { - return DecimalUtils.toDecimal(value); - } - - public Duration convertFromBigDecimal(BigDecimal value) { - return DecimalUtils.toDuration(value); - } - @Override public void bind(DataBind bind, Duration value) throws SQLException { if (value == null) { @@ -48,25 +40,6 @@ public class ScalarTypeDurationWithNanos extends ScalarTypeDuration { return convertFromBigDecimal(dataReader.getBigDecimal()); } - @Override - public Duration readData(DataInput dataInput) throws IOException { - if (!dataInput.readBoolean()) { - return null; - } else { - return convertFromBigDecimal(new BigDecimal(dataInput.readUTF())); - } - } - - @Override - public void writeData(DataOutput dataOutput, Duration value) throws IOException { - if (value == null) { - dataOutput.writeBoolean(false); - } else { - dataOutput.writeBoolean(true); - dataOutput.writeUTF(convertToBigDecimal(value).toString()); - } - } - @Override public Object toJdbcType(Object value) { if (value instanceof BigDecimal) return value; diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTime.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTime.java index b8a24312c..40a45f0a3 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTime.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTime.java @@ -10,31 +10,48 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.sql.SQLException; +import java.sql.Time; import java.sql.Types; import java.time.LocalTime; -import java.time.Year; /** - * ScalarType for java.time.Year + * ScalarType for java.time.LocalTime stored as JDBC Time. */ public class ScalarTypeLocalTime extends ScalarTypeBase { public ScalarTypeLocalTime() { - super(LocalTime.class, true, Types.BIGINT); + super(LocalTime.class, false, Types.TIME); + } + + protected ScalarTypeLocalTime(int jdbcTtype) { + super(LocalTime.class, false, jdbcTtype); } @Override public void bind(DataBind bind, LocalTime value) throws SQLException { if (value == null) { - bind.setNull(Types.BIGINT); + bind.setNull(Types.TIME); } else { - bind.setLong(value.toNanoOfDay()); + bind.setTime(Time.valueOf(value)); } } @Override public LocalTime read(DataReader dataReader) throws SQLException { - return LocalTime.ofNanoOfDay(dataReader.getLong()); + Time time = dataReader.getTime(); + return (time == null) ? null : time.toLocalTime(); + } + + @Override + public Object toJdbcType(Object value) { + if (value instanceof Time) return value; + return Time.valueOf((LocalTime)value); + } + + @Override + public LocalTime toBeanType(Object value) { + if (value instanceof LocalTime) return (LocalTime) value; + return BasicTypeConverter.toTime(value).toLocalTime(); } @Override @@ -56,18 +73,6 @@ public class ScalarTypeLocalTime extends ScalarTypeBase { } } - @Override - public Object toJdbcType(Object value) { - if (value instanceof Long) return value; - return ((LocalTime)value).toNanoOfDay(); - } - - @Override - public LocalTime toBeanType(Object value) { - if (value instanceof LocalTime) return (LocalTime) value; - return LocalTime.ofNanoOfDay(BasicTypeConverter.toLong(value)); - } - @Override public String formatValue(LocalTime v) { return v.toString(); diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java new file mode 100644 index 000000000..d72f36222 --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java @@ -0,0 +1,45 @@ +package com.avaje.ebeaninternal.server.type; + +import com.avaje.ebeaninternal.server.core.BasicTypeConverter; + +import java.sql.SQLException; +import java.sql.Types; +import java.time.LocalTime; + +/** + * ScalarType for java.time.LocalTime stored with Nanos as DB BIGINT type. + */ +public class ScalarTypeLocalTimeWithNanos extends ScalarTypeLocalTime { + + public ScalarTypeLocalTimeWithNanos() { + super(Types.BIGINT); + } + + @Override + public void bind(DataBind bind, LocalTime value) throws SQLException { + if (value == null) { + bind.setNull(Types.BIGINT); + } else { + bind.setLong(value.toNanoOfDay()); + } + } + + @Override + public LocalTime read(DataReader dataReader) throws SQLException { + Long value = dataReader.getLong(); + return (value == null) ? null : LocalTime.ofNanoOfDay(value); + } + + @Override + public Object toJdbcType(Object value) { + if (value instanceof Long) return value; + return ((LocalTime)value).toNanoOfDay(); + } + + @Override + public LocalTime toBeanType(Object value) { + if (value instanceof LocalTime) return (LocalTime) value; + return LocalTime.ofNanoOfDay(BasicTypeConverter.toLong(value)); + } + +} diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeYear.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeYear.java index 019407dbb..b572284dd 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeYear.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeYear.java @@ -33,7 +33,8 @@ public class ScalarTypeYear extends ScalarTypeBase { @Override public Year read(DataReader dataReader) throws SQLException { - return Year.of(dataReader.getInt()); + Integer value = dataReader.getInt(); + return (value == null) ? null : Year.of(value); } @Override diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeTest.java index b60deb3cc..43256a58f 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeTest.java +++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeTest.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.JsonToken; import org.junit.Test; import java.io.*; +import java.sql.Time; import java.time.LocalTime; import static org.junit.Assert.*; @@ -41,13 +42,14 @@ public class ScalarTypeLocalTimeTest { @Test public void testToJdbcType() throws Exception { - LocalTime localTime = LocalTime.of(9, 23, 45); - long asNanos = localTime.toNanoOfDay(); - Object val1 = type.toJdbcType(localTime); - Object val2 = type.toJdbcType(asNanos); + LocalTime localTime = LocalTime.of(9, 23, 45, 123); + Time time = Time.valueOf(localTime); - assertEquals(asNanos, val1); - assertEquals(asNanos, val2); + Object val1 = type.toJdbcType(localTime); + Object val2 = type.toJdbcType(time); + + assertEquals(time, val1); + assertEquals(time, val2); } @Test @@ -55,7 +57,7 @@ public class ScalarTypeLocalTimeTest { LocalTime localTime = LocalTime.of(9, 23, 45); LocalTime val1 = type.toBeanType(localTime); - LocalTime val2 = type.toBeanType(localTime.toNanoOfDay()); + LocalTime val2 = type.toBeanType(Time.valueOf(localTime)); assertEquals(localTime, val1); assertEquals(localTime, val2); diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanosTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanosTest.java new file mode 100644 index 000000000..fae98e930 --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanosTest.java @@ -0,0 +1,119 @@ +package com.avaje.ebeaninternal.server.type; + +import com.avaje.ebean.text.TextException; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import org.junit.Test; + +import java.io.*; +import java.time.LocalTime; + +import static org.junit.Assert.*; + +public class ScalarTypeLocalTimeWithNanosTest { + + ScalarTypeLocalTimeWithNanos type = new ScalarTypeLocalTimeWithNanos(); + + @Test + public void testReadData() throws Exception { + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(os); + + LocalTime localTime = LocalTime.of(9, 23, 45, 115); + type.writeData(out, localTime); + type.writeData(out, null); + out.flush(); + out.close(); + + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream in = new ObjectInputStream(is); + + LocalTime val1 = type.readData(in); + LocalTime val2 = type.readData(in); + + assertEquals(localTime, val1); + assertNull(val2); + } + + @Test + public void testToJdbcType() throws Exception { + + LocalTime localTime = LocalTime.of(9, 23, 45, 115); + long asNanos = localTime.toNanoOfDay(); + Object val1 = type.toJdbcType(localTime); + Object val2 = type.toJdbcType(asNanos); + + assertEquals(asNanos, val1); + assertEquals(asNanos, val2); + } + + @Test + public void testToBeanType() throws Exception { + + LocalTime localTime = LocalTime.of(9, 23, 45); + LocalTime val1 = type.toBeanType(localTime); + LocalTime val2 = type.toBeanType(localTime.toNanoOfDay()); + + assertEquals(localTime, val1); + assertEquals(localTime, val2); + } + + @Test + public void testFormatValue() throws Exception { + + LocalTime localTime = LocalTime.of(9, 23, 45); + String formatted = type.formatValue(localTime); + assertEquals("09:23:45", formatted); + } + + @Test + public void testParse() throws Exception { + + LocalTime localTime = LocalTime.of(9, 23, 45); + LocalTime val1 = type.parse("09:23:45"); + assertEquals(localTime, val1); + } + + @Test + public void testIsDateTimeCapable() throws Exception { + + assertFalse(type.isDateTimeCapable()); + } + + @Test(expected = TextException.class) + public void testConvertFromMillis() throws Exception { + + type.convertFromMillis(1234); + } + + @Test + public void testJsonRead() throws Exception { + + + LocalTime localTime = LocalTime.of(9, 23, 45); + + + StringWriter writer = new StringWriter(); + JsonFactory factory = new JsonFactory(); + JsonGenerator generator = factory.createGenerator(writer); + generator.writeStartObject(); + type.jsonWrite(generator, "key", localTime); + generator.writeEndObject(); + generator.flush(); + + JsonParser parser = factory.createParser(writer.toString()); + JsonToken token = parser.nextToken(); + assertEquals(JsonToken.START_OBJECT, token); + token = parser.nextToken(); + assertEquals(JsonToken.FIELD_NAME, token); + token = parser.nextToken(); + + LocalTime val1 = type.jsonRead(parser, token); + assertEquals(localTime, val1); + + } + +} \ No newline at end of file