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))