From 36daba0f421fb41dc0a960d9a9d842c69f4970d9 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 8 Aug 2017 10:04:16 +0200 Subject: [PATCH] DATAJDBC-119 - Fix broken tests with other databases. Fixed sql scripts for the various databases. Postgres doesn't handle BigInts properly when just past to setObject. It needs special SqlType information. Postgres can only handle BigInts up to Long.MAX_VALUE. MySql stores dates only with seconds precision. --- .../data/jdbc/core/JdbcEntityTemplate.java | 9 +++- ...oryPropertyConversionIntegrationTests.java | 46 ++++++++++++------- src/test/resources/logback.xml | 2 +- ...bcEntityTemplateIntegrationTests-mysql.sql | 5 ++ ...ntityTemplateIntegrationTests-postgres.sql | 8 ++++ ...JdbcRepositoriesIntegrationTests-mysql.sql | 1 + ...cRepositoriesIntegrationTests-postgres.sql | 2 + ...opertyConversionIntegrationTests-mysql.sql | 1 + ...rtyConversionIntegrationTests-postgres.sql | 2 + 9 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-mysql.sql create mode 100644 src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-postgres.sql create mode 100644 src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-mysql.sql create mode 100644 src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-postgres.sql create mode 100644 src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-mysql.sql create mode 100644 src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-postgres.sql diff --git a/src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java b/src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java index 9744d268..e55754fb 100644 --- a/src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java +++ b/src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jdbc.core; +import java.math.BigInteger; +import java.sql.Types; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -49,6 +51,7 @@ import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -279,7 +282,11 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { Object value = persistentEntity.getPropertyAccessor(instance).getProperty(property); Object convertedValue = convert(value, property.getColumnType()); - parameters.put(property.getColumnName(), convertedValue); + if (convertedValue instanceof BigInteger) { + parameters.put(property.getColumnName(), new SqlParameterValue(Types.BIGINT, convertedValue)); + } else { + parameters.put(property.getColumnName(), convertedValue); + } } }); diff --git a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryPropertyConversionIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryPropertyConversionIntegrationTests.java index 99b167ad..b75b68cd 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryPropertyConversionIntegrationTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryPropertyConversionIntegrationTests.java @@ -15,8 +15,7 @@ */ package org.springframework.data.jdbc.repository; -import static java.util.Arrays.*; -import static java.util.Collections.singletonList; +import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; import lombok.Data; @@ -26,11 +25,12 @@ import java.math.BigInteger; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; -import java.time.ZonedDateTime; +import java.time.ZoneOffset; import java.util.Collections; import java.util.Date; import org.assertj.core.api.Condition; +import org.assertj.core.api.SoftAssertions; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -53,6 +53,12 @@ import org.springframework.transaction.annotation.Transactional; * Tests storing and retrieving various data types that are considered essential and that might need conversion to * something the database driver can handle. * + * + * no millis + * no large BigIntegers + * + * + * * @author Jens Schauder */ @ContextConfiguration @@ -78,7 +84,7 @@ public class JdbcRepositoryPropertyConversionIntegrationTests { @Bean ApplicationListener applicationListener() { return (ApplicationListener) beforeInsert -> ((EntityWithColumnsRequiringConversions) beforeInsert - .getEntity()).setIdTimestamp(LocalDateTime.now()); + .getEntity()).setIdTimestamp(getNow()); } } @@ -94,14 +100,15 @@ public class JdbcRepositoryPropertyConversionIntegrationTests { EntityWithColumnsRequiringConversions entity = repository.save(createDummyEntity()); assertThat(repository.findById(entity.getIdTimestamp())).hasValueSatisfying(it -> { - - assertThat(it.getIdTimestamp()).isEqualTo(entity.getIdTimestamp()); - assertThat(it.getSomeEnum()).isEqualTo(entity.getSomeEnum()); - assertThat(it.getBigDecimal()).isEqualTo(entity.getBigDecimal()); - assertThat(it.isBool()).isEqualTo(entity.isBool()); - assertThat(it.getBigInteger()).isEqualTo(entity.getBigInteger()); - assertThat(it.getDate()).is(representingTheSameAs(entity.getDate())); - assertThat(it.getLocalDateTime()).isEqualTo(entity.getLocalDateTime()); + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(it.getIdTimestamp()).isEqualTo(entity.getIdTimestamp()); + softly.assertThat(it.getSomeEnum()).isEqualTo(entity.getSomeEnum()); + softly.assertThat(it.getBigDecimal()).isEqualTo(entity.getBigDecimal()); + softly.assertThat(it.isBool()).isEqualTo(entity.isBool()); + softly.assertThat(it.getBigInteger()).isEqualTo(entity.getBigInteger()); + softly.assertThat(it.getDate()).is(representingTheSameAs(entity.getDate())); + softly.assertThat(it.getLocalDateTime()).isEqualTo(entity.getLocalDateTime()); + softly.assertAll(); }); } @@ -145,15 +152,22 @@ public class JdbcRepositoryPropertyConversionIntegrationTests { EntityWithColumnsRequiringConversions entity = new EntityWithColumnsRequiringConversions(); entity.setSomeEnum(SomeEnum.VALUE); - entity.setBigDecimal(new BigDecimal(Double.MAX_VALUE).multiply(BigDecimal.TEN)); + entity.setBigDecimal(new BigDecimal("123456789012345678901234567890123456789012345678901234567890")); entity.setBool(true); - entity.setBigInteger(BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.TEN)); - entity.setDate(new Date()); - entity.setLocalDateTime(LocalDateTime.now()); + // Postgres doesn't seem to be able to handle BigInts larger then a Long, since the driver reads them as Long + entity.setBigInteger(BigInteger.valueOf(Long.MAX_VALUE)); + entity.setDate(Date.from(getNow().toInstant(ZoneOffset.UTC))); + entity.setLocalDateTime(getNow()); return entity; } + private static LocalDateTime getNow() { + LocalDateTime now = LocalDateTime.now(); + + return now.withNano(0); + } + private Condition representingTheSameAs(Date other) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index af95b497..9aab4bd6 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -9,7 +9,7 @@ - + diff --git a/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-mysql.sql b/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-mysql.sql new file mode 100644 index 00000000..a3a84905 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-mysql.sql @@ -0,0 +1,5 @@ +CREATE TABLE LEGOSET ( id BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(30)); +CREATE TABLE MANUAL ( id BIGINT AUTO_INCREMENT PRIMARY KEY, LEGOSET BIGINT, CONTENT VARCHAR(2000)); + +ALTER TABLE MANUAL ADD FOREIGN KEY (LEGOSET) +REFERENCES LEGOSET(id); diff --git a/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-postgres.sql b/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-postgres.sql new file mode 100644 index 00000000..e13b2925 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.core/JdbcEntityTemplateIntegrationTests-postgres.sql @@ -0,0 +1,8 @@ +DROP TABLE MANUAL; +DROP TABLE LEGOSET; + +CREATE TABLE LEGOSET ( id SERIAL PRIMARY KEY, NAME VARCHAR(30)); +CREATE TABLE MANUAL ( id SERIAL PRIMARY KEY, LEGOSET BIGINT, CONTENT VARCHAR(2000)); + +ALTER TABLE MANUAL ADD FOREIGN KEY (LEGOSET) +REFERENCES LEGOSET(id); diff --git a/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-mysql.sql b/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-mysql.sql new file mode 100644 index 00000000..808c99e6 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-mysql.sql @@ -0,0 +1 @@ +CREATE TABLE DummyEntity ( id BIGINT AUTO_INCREMENT PRIMARY KEY) \ No newline at end of file diff --git a/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-postgres.sql b/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-postgres.sql new file mode 100644 index 00000000..0a855395 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-postgres.sql @@ -0,0 +1,2 @@ +DROP TABLE DummyEntity +CREATE TABLE DummyEntity ( id SERIAL PRIMARY KEY) \ No newline at end of file diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-mysql.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-mysql.sql new file mode 100644 index 00000000..91f0b575 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-mysql.sql @@ -0,0 +1 @@ +CREATE TABLE ENTITYWITHCOLUMNSREQUIRINGCONVERSIONS ( idTimestamp DATETIME PRIMARY KEY, bool boolean, SOMEENUM VARCHAR(100), bigDecimal DECIMAL(65), bigInteger DECIMAL(20), date DATETIME, localDateTime DATETIME, zonedDateTime VARCHAR(30)) diff --git a/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-postgres.sql b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-postgres.sql new file mode 100644 index 00000000..0384fb55 --- /dev/null +++ b/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-postgres.sql @@ -0,0 +1,2 @@ +DROP TABLE ENTITYWITHCOLUMNSREQUIRINGCONVERSIONS; +CREATE TABLE ENTITYWITHCOLUMNSREQUIRINGCONVERSIONS ( idTimestamp TIMESTAMP PRIMARY KEY, bool boolean, SOMEENUM VARCHAR(100), bigDecimal DECIMAL(65), bigInteger BIGINT, date TIMESTAMP, localDateTime TIMESTAMP, zonedDateTime VARCHAR(30))