From c5df8f3d1c978e46ff8bd73958aefaa1486ef1b1 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 14 Jan 2022 10:57:50 +0100 Subject: [PATCH 01/51] Prepare 2.4 M1 (2021.2.0). See #1088 --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 2c64717780..0a74c396bd 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-SNAPSHOT + 2.7.0-M1 spring-data-jdbc - 2.7.0-SNAPSHOT + 2.7.0-M1 reuseReports @@ -276,8 +276,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 64e438568d..3dbd606f0c 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data JDBC 2.3 GA (2021.1.0) +Spring Data JDBC 2.4 M1 (2021.2.0) Copyright (c) [2017-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -30,5 +30,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 38a8089cb548977991a97788d919fa430c57f241 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 14 Jan 2022 10:58:16 +0100 Subject: [PATCH 02/51] Release version 2.4 M1 (2021.2.0). See #1088 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 0a74c396bd..a8ec61a236 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M1 pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 0646c2846d..2bc9f10d99 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M1 ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 11114a795e..d08fc0d1e9 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-SNAPSHOT + 2.4.0-M1 Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M1 diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index a6eb48c891..2c66ccb09b 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-SNAPSHOT + 2.4.0-M1 Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M1 From 51ffa1c59fa70731b2c645513321c9ff9c8ff21e Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 14 Jan 2022 11:07:59 +0100 Subject: [PATCH 03/51] Prepare next development iteration. See #1088 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index a8ec61a236..0a74c396bd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M1 + 2.4.0-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 2bc9f10d99..0646c2846d 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M1 + 2.4.0-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index d08fc0d1e9..11114a795e 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-M1 + 2.4.0-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M1 + 2.4.0-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 2c66ccb09b..a6eb48c891 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-M1 + 2.4.0-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M1 + 2.4.0-SNAPSHOT From cb5e3271a4789595300c4a0e2cb684dac3f5985d Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 14 Jan 2022 11:08:02 +0100 Subject: [PATCH 04/51] After release cleanups. See #1088 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0a74c396bd..2c64717780 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-M1 + 2.7.0-SNAPSHOT spring-data-jdbc - 2.7.0-M1 + 2.7.0-SNAPSHOT reuseReports @@ -276,8 +276,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From d879f21f57056c7eb84302654a95143f59e3ad57 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Jan 2022 09:08:59 +0100 Subject: [PATCH 05/51] Prepare 2.4 M2 (2021.2.0). See #1131 --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 2c64717780..e55043e2bd 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-SNAPSHOT + 2.7.0-M2 spring-data-jdbc - 2.7.0-SNAPSHOT + 2.7.0-M2 reuseReports @@ -276,8 +276,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 3dbd606f0c..c3d360e056 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data JDBC 2.4 M1 (2021.2.0) +Spring Data JDBC 2.4 M2 (2021.2.0) Copyright (c) [2017-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -31,5 +31,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 76ece50f2b0a638c44a3e068f7456d1cced63007 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Jan 2022 09:09:34 +0100 Subject: [PATCH 06/51] Release version 2.4 M2 (2021.2.0). See #1131 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index e55043e2bd..5992dc1d2d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M2 pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 0646c2846d..cb4596228f 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M2 ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 11114a795e..349c604731 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-SNAPSHOT + 2.4.0-M2 Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M2 diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index a6eb48c891..6a7225368d 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-SNAPSHOT + 2.4.0-M2 Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M2 From dce0e36c9091a541cd948518384854e49cf3e0e9 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Jan 2022 09:21:29 +0100 Subject: [PATCH 07/51] Prepare next development iteration. See #1131 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 5992dc1d2d..e55043e2bd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M2 + 2.4.0-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index cb4596228f..0646c2846d 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M2 + 2.4.0-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 349c604731..11114a795e 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-M2 + 2.4.0-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M2 + 2.4.0-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 6a7225368d..a6eb48c891 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-M2 + 2.4.0-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M2 + 2.4.0-SNAPSHOT From eee773ea829403f0a3802aad046177e559903ea4 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Jan 2022 09:21:32 +0100 Subject: [PATCH 08/51] After release cleanups. See #1131 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e55043e2bd..2c64717780 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-M2 + 2.7.0-SNAPSHOT spring-data-jdbc - 2.7.0-M2 + 2.7.0-SNAPSHOT reuseReports @@ -276,8 +276,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From c4933c0be9ac2628c84793e4303ada163711c0f7 Mon Sep 17 00:00:00 2001 From: Chirag Tailor Date: Tue, 25 Jan 2022 11:45:10 -0600 Subject: [PATCH 09/51] Support element conversion of array results. This is achieved by passing the full availabe type information of the conversion target to the conversion service. This broke a test which wasn't functional in the first place which becomes obvious when adding the proper assertion. Closes #1046 Original pull request #1144 --- .../jdbc/core/convert/BasicJdbcConverter.java | 13 +++------- ...JdbcAggregateTemplateIntegrationTests.java | 17 ++++++------ .../convert/EntityRowMapperUnitTests.java | 7 +++-- ...egateTemplateIntegrationTests-postgres.sql | 2 +- .../conversion/BasicRelationalConverter.java | 17 ++++++------ .../BasicRelationalConverterUnitTests.java | 26 +++++++++++++++---- 6 files changed, 48 insertions(+), 34 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java index 312eb8bab2..6114f5b9ca 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,6 +65,7 @@ * @author Jens Schauder * @author Christoph Strobl * @author Myeonghyeon Lee + * @author Chirag Tailor * @see MappingContext * @see SimpleTypeHolder * @see CustomConversions @@ -222,17 +223,9 @@ public Object readValue(@Nullable Object value, TypeInformation type) { return value; } - if (getConversions().hasCustomReadTarget(value.getClass(), type.getType())) { - - TypeDescriptor sourceDescriptor = TypeDescriptor.valueOf(value.getClass()); - TypeDescriptor targetDescriptor = createTypeDescriptor(type); - - return getConversionService().convert(value, sourceDescriptor, targetDescriptor); - } - if (value instanceof Array) { try { - return readValue(((Array) value).getArray(), type); + return super.readValue(((Array) value).getArray(), type); } catch (SQLException | ConverterNotFoundException e) { LOG.info("Failed to extract a value of type %s from an Array. Attempting to use standard conversions.", e); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 7c3f0c4f39..32e8b15afd 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,6 @@ import static org.springframework.data.jdbc.testing.TestDatabaseFeatures.Feature.*; import static org.springframework.test.context.TestExecutionListeners.MergeMode.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.With; - import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; @@ -69,6 +64,11 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Value; +import lombok.With; + /** * Integration tests for {@link JdbcAggregateTemplate}. * @@ -81,6 +81,7 @@ * @author Clemens Hahn * @author Milan Milanov * @author Mikhail Polivakha + * @author Chirag Tailor */ @ContextConfiguration @Transactional @@ -574,7 +575,7 @@ public void saveAndLoadAnEntityWithListOfDouble() { assertThat(reloaded.digits).isEqualTo(Arrays.asList(1.2, 1.3, 1.4)); } - @Test // GH-1033 + @Test // GH-1033, GH-1046 @EnabledOnFeature(SUPPORTS_ARRAYS) public void saveAndLoadAnEntityWithListOfFloat() { @@ -590,7 +591,7 @@ public void saveAndLoadAnEntityWithListOfFloat() { assertThat(reloaded).isNotNull(); assertThat(reloaded.id).isEqualTo(saved.id); - + assertThat(reloaded.digits).isEqualTo(values); } @Test // DATAJDBC-259 diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java index a4cd975c4b..63ddfa8309 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ import javax.naming.OperationNotSupportedException; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; import org.mockito.invocation.InvocationOnMock; @@ -74,6 +75,7 @@ * @author Bastian Wilhelm * @author Christoph Strobl * @author Myeonghyeon Lee + * @author Chirag Tailor */ public class EntityRowMapperUnitTests { @@ -280,6 +282,7 @@ public void handlesMixedProperties() throws SQLException { .containsSequence("111", "222", "333"); } + @Disabled("Assertion was updated for correctness and now this test fails. Unclear what it is intended to test and if it is still necessary.") @Test // DATAJDBC-273 public void handlesNonSimplePropertyInConstructor() throws SQLException { @@ -289,7 +292,7 @@ public void handlesNonSimplePropertyInConstructor() throws SQLException { EntityWithListInConstructor extracted = createRowMapper(EntityWithListInConstructor.class).mapRow(rs, 1); - assertThat(extracted.content).hasSize(2); + assertThat(extracted.content).containsExactly(new Trivial(1L, "one"), new Trivial(2L, "two")); } @Test // DATAJDBC-359 diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql index c21ec744bf..3482135adc 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql @@ -71,7 +71,7 @@ CREATE TABLE DOUBLE_LIST_OWNER CREATE TABLE FLOAT_LIST_OWNER ( ID SERIAL PRIMARY KEY, - DIGITS FLOAT[10] + DIGITS REAL[10] ); CREATE TABLE BYTE_ARRAY_OWNER diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java index 7da85cedee..d761aba0fb 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ * * @author Mark Paluch * @author Jens Schauder + * @author Chirag Tailor * @see MappingContext * @see SimpleTypeHolder * @see CustomConversions @@ -168,7 +169,7 @@ public Object readValue(@Nullable Object value, TypeInformation type) { return getConversionService().convert(value, sourceDescriptor, targetDescriptor); } - return getPotentiallyConvertedSimpleRead(value, type.getType()); + return getPotentiallyConvertedSimpleRead(value, type); } /* @@ -235,14 +236,14 @@ private Object getPotentiallyConvertedSimpleWrite(Object value) { * {@link Enum} handling or returns the value as is. * * @param value to be converted. May be {@code null}.. - * @param target may be {@code null}.. + * @param type {@link TypeInformation} into which the value is to be converted. Must not be {@code null}. * @return the converted value if a conversion applies or the original value. Might return {@code null}. */ @Nullable @SuppressWarnings({ "rawtypes", "unchecked" }) - private Object getPotentiallyConvertedSimpleRead(@Nullable Object value, @Nullable Class target) { - - if (value == null || target == null || ClassUtils.isAssignableValue(target, value)) { + private Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation type) { + Class target = type.getType(); + if (ClassUtils.isAssignableValue(target, value)) { return value; } @@ -250,10 +251,10 @@ private Object getPotentiallyConvertedSimpleRead(@Nullable Object value, @Nullab return Enum.valueOf((Class) target, value.toString()); } - return conversionService.convert(value, target); + return conversionService.convert(value, TypeDescriptor.forObject(value), createTypeDescriptor(type)); } - protected static TypeDescriptor createTypeDescriptor(TypeInformation type) { + private static TypeDescriptor createTypeDescriptor(TypeInformation type) { List> typeArguments = type.getTypeArguments(); Class[] generics = new Class[typeArguments.size()]; diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java index 241b9e02aa..5499b83b52 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +17,12 @@ import static org.assertj.core.api.Assertions.*; -import lombok.Data; -import lombok.Value; - +import java.util.Arrays; +import java.util.List; import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import org.springframework.core.convert.converter.GenericConverter; import org.springframework.data.convert.ConverterBuilder; import org.springframework.data.convert.CustomConversions; @@ -33,11 +31,16 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; + +import lombok.Data; +import lombok.Value; /** * Unit tests for {@link BasicRelationalConverter}. * * @author Mark Paluch + * @author Chirag Tailor */ public class BasicRelationalConverterUnitTests { @@ -88,6 +91,14 @@ public void shouldConvertStringToEnum() { assertThat(result).isEqualTo(MyEnum.OFF); } + @Test // GH-1046 + void shouldConvertArrayElementsToTargetElementType() throws NoSuchMethodException { + TypeInformation typeInformation = ClassTypeInformation.fromReturnTypeOf(EntityWithArray.class.getMethod("getFloats")); + Double[] value = {1.2d, 1.3d, 1.4d}; + Object result = converter.readValue(value, typeInformation); + assertThat(result).isEqualTo(Arrays.asList(1.2f, 1.3f, 1.4f)); + } + @Test // DATAJDBC-235 @SuppressWarnings("unchecked") public void shouldCreateInstance() { @@ -116,6 +127,11 @@ public void shouldConsiderReadConverter() { assertThat(result).isEqualTo(new MyValue("hello-world")); } + @Data + static class EntityWithArray { + List floats; + } + @Data static class MyEntity { boolean flag; From 45e15b1593f5de952a57990cd8de8d8dcb0de1d4 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 31 Jan 2022 15:38:19 +0100 Subject: [PATCH 10/51] Replaces broken test with a working one. See #1046, #498 Original pull request #1144 --- ...JdbcAggregateTemplateIntegrationTests.java | 67 +++++++++++++++---- .../convert/EntityRowMapperUnitTests.java | 22 ------ ...egateTemplateIntegrationTests-postgres.sql | 6 +- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 32e8b15afd..8a3bccb0fa 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -15,15 +15,20 @@ */ package org.springframework.data.jdbc.core; +import static java.util.Arrays.*; import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.SoftAssertions.*; import static org.springframework.data.jdbc.testing.TestDatabaseFeatures.Feature.*; import static org.springframework.test.context.TestExecutionListeners.MergeMode.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Value; +import lombok.With; + import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -44,6 +49,7 @@ import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Version; import org.springframework.data.domain.PageRequest; @@ -56,6 +62,7 @@ import org.springframework.data.jdbc.testing.TestDatabaseFeatures; import org.springframework.data.relational.core.conversion.DbActionExecutionException; import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.Table; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; @@ -64,11 +71,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.With; - /** * Integration tests for {@link JdbcAggregateTemplate}. * @@ -502,6 +504,21 @@ public void saveAndLoadAnEntityWithListOfElementsWithoutId() { assertThat(reloaded.content).extracting(e -> e.content).containsExactly("content"); } + @Test // GH-498 DATAJDBC-273 + @EnabledOnFeature(SUPPORTS_QUOTED_IDS) + public void saveAndLoadAnEntityWithListOfElementsInConstructor() { + + ElementNoId element = new ElementNoId(); + element.content = "content"; + ListParentAllArgs entity = new ListParentAllArgs("name", asList(element)); + + entity = template.save(entity); + + ListParentAllArgs reloaded = template.findById(entity.id, ListParentAllArgs.class); + + assertThat(reloaded.content).extracting(e -> e.content).containsExactly("content"); + } + @Test // DATAJDBC-259 @EnabledOnFeature(SUPPORTS_ARRAYS) public void saveAndLoadAnEntityWithArray() { @@ -544,7 +561,7 @@ public void saveAndLoadAnEntityWithMultidimensionalArray() { public void saveAndLoadAnEntityWithList() { ListOwner arrayOwner = new ListOwner(); - arrayOwner.digits.addAll(Arrays.asList("one", "two", "three")); + arrayOwner.digits.addAll(asList("one", "two", "three")); ListOwner saved = template.save(arrayOwner); @@ -554,7 +571,7 @@ public void saveAndLoadAnEntityWithList() { assertThat(reloaded).isNotNull(); assertThat(reloaded.id).isEqualTo(saved.id); - assertThat(reloaded.digits).isEqualTo(Arrays.asList("one", "two", "three")); + assertThat(reloaded.digits).isEqualTo(asList("one", "two", "three")); } @Test // GH-1033 @@ -562,7 +579,7 @@ public void saveAndLoadAnEntityWithList() { public void saveAndLoadAnEntityWithListOfDouble() { DoubleListOwner doubleListOwner = new DoubleListOwner(); - doubleListOwner.digits.addAll(Arrays.asList(1.2, 1.3, 1.4)); + doubleListOwner.digits.addAll(asList(1.2, 1.3, 1.4)); DoubleListOwner saved = template.save(doubleListOwner); @@ -572,7 +589,7 @@ public void saveAndLoadAnEntityWithListOfDouble() { assertThat(reloaded).isNotNull(); assertThat(reloaded.id).isEqualTo(saved.id); - assertThat(reloaded.digits).isEqualTo(Arrays.asList(1.2, 1.3, 1.4)); + assertThat(reloaded.digits).isEqualTo(asList(1.2, 1.3, 1.4)); } @Test // GH-1033, GH-1046 @@ -580,7 +597,7 @@ public void saveAndLoadAnEntityWithListOfDouble() { public void saveAndLoadAnEntityWithListOfFloat() { FloatListOwner floatListOwner = new FloatListOwner(); - final List values = Arrays.asList(1.2f, 1.3f, 1.4f); + final List values = asList(1.2f, 1.3f, 1.4f); floatListOwner.digits.addAll(values); FloatListOwner saved = template.save(floatListOwner); @@ -599,7 +616,7 @@ public void saveAndLoadAnEntityWithListOfFloat() { public void saveAndLoadAnEntityWithSet() { SetOwner setOwner = new SetOwner(); - setOwner.digits.addAll(Arrays.asList("one", "two", "three")); + setOwner.digits.addAll(asList("one", "two", "three")); SetOwner saved = template.save(setOwner); @@ -609,7 +626,7 @@ public void saveAndLoadAnEntityWithSet() { assertThat(reloaded).isNotNull(); assertThat(reloaded.id).isEqualTo(saved.id); - assertThat(reloaded.digits).isEqualTo(new HashSet<>(Arrays.asList("one", "two", "three"))); + assertThat(reloaded.digits).isEqualTo(new HashSet<>(asList("one", "two", "three"))); } @Test // DATAJDBC-327 @@ -1011,13 +1028,37 @@ static class ChildNoId { private String content; } + @Table("LIST_PARENT") static class ListParent { @Column("id4") @Id private Long id; String name; + @MappedCollection(idColumn = "LIST_PARENT") List content = new ArrayList<>(); } + @Table("LIST_PARENT") + static class ListParentAllArgs { + + @Column("id4") @Id + private final Long id; + private final String name; + @MappedCollection(idColumn = "LIST_PARENT") + private final List content = new ArrayList<>(); + + @PersistenceConstructor + ListParentAllArgs(Long id, String name, List content) { + + this.id = id; + this.name = name; + this.content.addAll(content); + } + + ListParentAllArgs(String name, List content) { + this(null, name, content); + } + } + static class ElementNoId { private String content; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java index 63ddfa8309..7983cc99c6 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java @@ -44,7 +44,6 @@ import javax.naming.OperationNotSupportedException; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; import org.mockito.invocation.InvocationOnMock; @@ -282,19 +281,6 @@ public void handlesMixedProperties() throws SQLException { .containsSequence("111", "222", "333"); } - @Disabled("Assertion was updated for correctness and now this test fails. Unclear what it is intended to test and if it is still necessary.") - @Test // DATAJDBC-273 - public void handlesNonSimplePropertyInConstructor() throws SQLException { - - ResultSet rs = mockResultSet(singletonList("ID"), // - ID_FOR_ENTITY_REFERENCING_LIST); - rs.next(); - - EntityWithListInConstructor extracted = createRowMapper(EntityWithListInConstructor.class).mapRow(rs, 1); - - assertThat(extracted.content).containsExactly(new Trivial(1L, "one"), new Trivial(2L, "two")); - } - @Test // DATAJDBC-359 public void chainedEntitiesWithoutId() throws SQLException { @@ -787,14 +773,6 @@ MixedProperties withThree(String three) { } } - @AllArgsConstructor - static class EntityWithListInConstructor { - - @Id final Long id; - - final List content; - } - static class NoIdChain0 { String zeroValue; } diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql index 3482135adc..620c75f46b 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql @@ -2,8 +2,8 @@ DROP TABLE MANUAL; DROP TABLE LEGO_SET; DROP TABLE ONE_TO_ONE_PARENT; DROP TABLE Child_No_Id; -DROP TABLE LIST_PARENT; DROP TABLE element_no_id; +DROP TABLE "LIST_PARENT"; DROP TABLE ARRAY_OWNER; DROP TABLE BYTE_ARRAY_OWNER; DROP TABLE CHAIN4; @@ -42,7 +42,7 @@ CREATE TABLE Child_No_Id content VARCHAR(30) ); -CREATE TABLE LIST_PARENT +CREATE TABLE "LIST_PARENT" ( "id4" SERIAL PRIMARY KEY, NAME VARCHAR(100) @@ -52,7 +52,7 @@ CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, - LIST_PARENT INTEGER + "LIST_PARENT" INTEGER ); CREATE TABLE "ARRAY_OWNER" From cef041f68318512c48e7d8abbad3df7b2710ccd7 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 31 Jan 2022 15:58:09 +0100 Subject: [PATCH 11/51] Polishing. See #1046 Original pull request #1144 --- ...JdbcAggregateTemplateIntegrationTests.java | 94 +++++++++---------- .../convert/EntityRowMapperUnitTests.java | 82 ++++++++-------- .../conversion/BasicRelationalConverter.java | 1 + .../BasicRelationalConverterUnitTests.java | 26 ++--- 4 files changed, 103 insertions(+), 100 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 8a3bccb0fa..4153ac6b3b 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -89,7 +89,7 @@ @Transactional @TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS) @ExtendWith(SpringExtension.class) -public class JdbcAggregateTemplateIntegrationTests { +class JdbcAggregateTemplateIntegrationTests { @Autowired JdbcAggregateOperations template; @Autowired NamedParameterJdbcOperations jdbcTemplate; @@ -194,7 +194,7 @@ private static LegoSet createLegoSet(String name) { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithReferencedEntityById() { + void saveAndLoadAnEntityWithReferencedEntityById() { template.save(legoSet); @@ -216,7 +216,7 @@ public void saveAndLoadAnEntityWithReferencedEntityById() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadManyEntitiesWithReferencedEntity() { + void saveAndLoadManyEntitiesWithReferencedEntity() { template.save(legoSet); @@ -229,7 +229,7 @@ public void saveAndLoadManyEntitiesWithReferencedEntity() { @Test // DATAJDBC-101 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadManyEntitiesWithReferencedEntitySorted() { + void saveAndLoadManyEntitiesWithReferencedEntitySorted() { template.save(createLegoSet("Lava")); template.save(createLegoSet("Star")); @@ -244,7 +244,7 @@ public void saveAndLoadManyEntitiesWithReferencedEntitySorted() { @Test // DATAJDBC-101 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() { + void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() { template.save(createLegoSet("Lava")); template.save(createLegoSet("Star")); @@ -259,7 +259,7 @@ public void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadManyEntitiesByIdWithReferencedEntity() { + void saveAndLoadManyEntitiesByIdWithReferencedEntity() { template.save(legoSet); @@ -271,7 +271,7 @@ public void saveAndLoadManyEntitiesByIdWithReferencedEntity() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithReferencedNullEntity() { + void saveAndLoadAnEntityWithReferencedNullEntity() { legoSet.setManual(null); @@ -284,7 +284,7 @@ public void saveAndLoadAnEntityWithReferencedNullEntity() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndDeleteAnEntityWithReferencedEntity() { + void saveAndDeleteAnEntityWithReferencedEntity() { template.save(legoSet); @@ -300,7 +300,7 @@ public void saveAndDeleteAnEntityWithReferencedEntity() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndDeleteAllWithReferencedEntity() { + void saveAndDeleteAllWithReferencedEntity() { template.save(legoSet); @@ -316,7 +316,7 @@ public void saveAndDeleteAllWithReferencedEntity() { @Test // DATAJDBC-112 @EnabledOnFeature({ SUPPORTS_QUOTED_IDS, SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES }) - public void updateReferencedEntityFromNull() { + void updateReferencedEntityFromNull() { legoSet.setManual(null); template.save(legoSet); @@ -335,7 +335,7 @@ public void updateReferencedEntityFromNull() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void updateReferencedEntityToNull() { + void updateReferencedEntityToNull() { template.save(legoSet); @@ -354,7 +354,7 @@ public void updateReferencedEntityToNull() { } @Test // DATAJDBC-438 - public void updateFailedRootDoesNotExist() { + void updateFailedRootDoesNotExist() { LegoSet entity = new LegoSet(); entity.setId(100L); // does not exist in the database @@ -366,7 +366,7 @@ public void updateFailedRootDoesNotExist() { @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void replaceReferencedEntity() { + void replaceReferencedEntity() { template.save(legoSet); @@ -388,7 +388,7 @@ public void replaceReferencedEntity() { @Test // DATAJDBC-112 @EnabledOnFeature({ SUPPORTS_QUOTED_IDS, TestDatabaseFeatures.Feature.SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES }) - public void changeReferencedEntity() { + void changeReferencedEntity() { template.save(legoSet); @@ -403,7 +403,7 @@ public void changeReferencedEntity() { @Test // DATAJDBC-266 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void oneToOneChildWithoutId() { + void oneToOneChildWithoutId() { OneToOneParent parent = new OneToOneParent(); @@ -420,7 +420,7 @@ public void oneToOneChildWithoutId() { @Test // DATAJDBC-266 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void oneToOneNullChildWithoutId() { + void oneToOneNullChildWithoutId() { OneToOneParent parent = new OneToOneParent(); @@ -436,7 +436,7 @@ public void oneToOneNullChildWithoutId() { @Test // DATAJDBC-266 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void oneToOneNullAttributes() { + void oneToOneNullAttributes() { OneToOneParent parent = new OneToOneParent(); @@ -452,7 +452,7 @@ public void oneToOneNullAttributes() { @Test // DATAJDBC-125 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithSecondaryReferenceNull() { + void saveAndLoadAnEntityWithSecondaryReferenceNull() { template.save(legoSet); @@ -465,7 +465,7 @@ public void saveAndLoadAnEntityWithSecondaryReferenceNull() { @Test // DATAJDBC-125 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithSecondaryReferenceNotNull() { + void saveAndLoadAnEntityWithSecondaryReferenceNotNull() { legoSet.alternativeInstructions = new Manual(); legoSet.alternativeInstructions.content = "alternative content"; @@ -487,7 +487,7 @@ public void saveAndLoadAnEntityWithSecondaryReferenceNotNull() { @Test // DATAJDBC-276 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithListOfElementsWithoutId() { + void saveAndLoadAnEntityWithListOfElementsWithoutId() { ListParent entity = new ListParent(); entity.name = "name"; @@ -506,7 +506,7 @@ public void saveAndLoadAnEntityWithListOfElementsWithoutId() { @Test // GH-498 DATAJDBC-273 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadAnEntityWithListOfElementsInConstructor() { + void saveAndLoadAnEntityWithListOfElementsInConstructor() { ElementNoId element = new ElementNoId(); element.content = "content"; @@ -521,7 +521,7 @@ public void saveAndLoadAnEntityWithListOfElementsInConstructor() { @Test // DATAJDBC-259 @EnabledOnFeature(SUPPORTS_ARRAYS) - public void saveAndLoadAnEntityWithArray() { + void saveAndLoadAnEntityWithArray() { ArrayOwner arrayOwner = new ArrayOwner(); arrayOwner.digits = new String[] { "one", "two", "three" }; @@ -539,7 +539,7 @@ public void saveAndLoadAnEntityWithArray() { @Test // DATAJDBC-259, DATAJDBC-512 @EnabledOnFeature(SUPPORTS_MULTIDIMENSIONAL_ARRAYS) - public void saveAndLoadAnEntityWithMultidimensionalArray() { + void saveAndLoadAnEntityWithMultidimensionalArray() { ArrayOwner arrayOwner = new ArrayOwner(); arrayOwner.multidimensional = new String[][] { { "one-a", "two-a", "three-a" }, { "one-b", "two-b", "three-b" } }; @@ -558,7 +558,7 @@ public void saveAndLoadAnEntityWithMultidimensionalArray() { @Test // DATAJDBC-259 @EnabledOnFeature(SUPPORTS_ARRAYS) - public void saveAndLoadAnEntityWithList() { + void saveAndLoadAnEntityWithList() { ListOwner arrayOwner = new ListOwner(); arrayOwner.digits.addAll(asList("one", "two", "three")); @@ -576,7 +576,7 @@ public void saveAndLoadAnEntityWithList() { @Test // GH-1033 @EnabledOnFeature(SUPPORTS_ARRAYS) - public void saveAndLoadAnEntityWithListOfDouble() { + void saveAndLoadAnEntityWithListOfDouble() { DoubleListOwner doubleListOwner = new DoubleListOwner(); doubleListOwner.digits.addAll(asList(1.2, 1.3, 1.4)); @@ -594,7 +594,7 @@ public void saveAndLoadAnEntityWithListOfDouble() { @Test // GH-1033, GH-1046 @EnabledOnFeature(SUPPORTS_ARRAYS) - public void saveAndLoadAnEntityWithListOfFloat() { + void saveAndLoadAnEntityWithListOfFloat() { FloatListOwner floatListOwner = new FloatListOwner(); final List values = asList(1.2f, 1.3f, 1.4f); @@ -613,7 +613,7 @@ public void saveAndLoadAnEntityWithListOfFloat() { @Test // DATAJDBC-259 @EnabledOnFeature(SUPPORTS_ARRAYS) - public void saveAndLoadAnEntityWithSet() { + void saveAndLoadAnEntityWithSet() { SetOwner setOwner = new SetOwner(); setOwner.digits.addAll(asList("one", "two", "three")); @@ -630,7 +630,7 @@ public void saveAndLoadAnEntityWithSet() { } @Test // DATAJDBC-327 - public void saveAndLoadAnEntityWithByteArray() { + void saveAndLoadAnEntityWithByteArray() { ByteArrayOwner owner = new ByteArrayOwner(); owner.binaryData = new byte[] { 1, 23, 42 }; @@ -646,7 +646,7 @@ public void saveAndLoadAnEntityWithByteArray() { @Test // DATAJDBC-340 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadLongChain() { + void saveAndLoadLongChain() { Chain4 chain4 = new Chain4(); chain4.fourValue = "omega"; @@ -675,7 +675,7 @@ public void saveAndLoadLongChain() { @Test // DATAJDBC-359 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void saveAndLoadLongChainWithoutIds() { + void saveAndLoadLongChainWithoutIds() { NoIdChain4 chain4 = new NoIdChain4(); chain4.fourValue = "omega"; @@ -705,7 +705,7 @@ public void saveAndLoadLongChainWithoutIds() { } @Test // DATAJDBC-223 - public void saveAndLoadLongChainOfListsWithoutIds() { + void saveAndLoadLongChainOfListsWithoutIds() { NoIdListChain4 saved = template.save(createNoIdTree()); @@ -716,7 +716,7 @@ public void saveAndLoadLongChainOfListsWithoutIds() { } @Test // DATAJDBC-223 - public void shouldDeleteChainOfListsWithoutIds() { + void shouldDeleteChainOfListsWithoutIds() { NoIdListChain4 saved = template.save(createNoIdTree()); template.deleteById(saved.four, NoIdListChain4.class); @@ -732,7 +732,7 @@ public void shouldDeleteChainOfListsWithoutIds() { } @Test // DATAJDBC-223 - public void saveAndLoadLongChainOfMapsWithoutIds() { + void saveAndLoadLongChainOfMapsWithoutIds() { NoIdMapChain4 saved = template.save(createNoIdMapTree()); @@ -743,7 +743,7 @@ public void saveAndLoadLongChainOfMapsWithoutIds() { } @Test // DATAJDBC-223 - public void shouldDeleteChainOfMapsWithoutIds() { + void shouldDeleteChainOfMapsWithoutIds() { NoIdMapChain4 saved = template.save(createNoIdMapTree()); template.deleteById(saved.four, NoIdMapChain4.class); @@ -760,7 +760,7 @@ public void shouldDeleteChainOfMapsWithoutIds() { @Test // DATAJDBC-431 @EnabledOnFeature(IS_HSQL) - public void readOnlyGetsLoadedButNotWritten() { + void readOnlyGetsLoadedButNotWritten() { WithReadOnly entity = new WithReadOnly(); entity.name = "Alfred"; @@ -774,7 +774,7 @@ public void readOnlyGetsLoadedButNotWritten() { } @Test // DATAJDBC-219 Test that immutable version attribute works as expected. - public void saveAndUpdateAggregateWithImmutableVersion() { + void saveAndUpdateAggregateWithImmutableVersion() { AggregateWithImmutableVersion aggregate = new AggregateWithImmutableVersion(null, null); aggregate = template.save(aggregate); @@ -805,7 +805,7 @@ public void saveAndUpdateAggregateWithImmutableVersion() { } @Test // DATAJDBC-219 Test that a delete with a version attribute works as expected. - public void deleteAggregateWithVersion() { + void deleteAggregateWithVersion() { AggregateWithImmutableVersion aggregate = new AggregateWithImmutableVersion(null, null); aggregate = template.save(aggregate); @@ -837,38 +837,38 @@ public void deleteAggregateWithVersion() { } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithLongVersion() { + void saveAndUpdateAggregateWithLongVersion() { saveAndUpdateAggregateWithVersion(new AggregateWithLongVersion(), Number::longValue); } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithPrimitiveLongVersion() { + void saveAndUpdateAggregateWithPrimitiveLongVersion() { saveAndUpdateAggregateWithPrimitiveVersion(new AggregateWithPrimitiveLongVersion(), Number::longValue); } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithIntegerVersion() { + void saveAndUpdateAggregateWithIntegerVersion() { saveAndUpdateAggregateWithVersion(new AggregateWithIntegerVersion(), Number::intValue); } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithPrimitiveIntegerVersion() { + void saveAndUpdateAggregateWithPrimitiveIntegerVersion() { saveAndUpdateAggregateWithPrimitiveVersion(new AggregateWithPrimitiveIntegerVersion(), Number::intValue); } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithShortVersion() { + void saveAndUpdateAggregateWithShortVersion() { saveAndUpdateAggregateWithVersion(new AggregateWithShortVersion(), Number::shortValue); } @Test // DATAJDBC-219 - public void saveAndUpdateAggregateWithPrimitiveShortVersion() { + void saveAndUpdateAggregateWithPrimitiveShortVersion() { saveAndUpdateAggregateWithPrimitiveVersion(new AggregateWithPrimitiveShortVersion(), Number::shortValue); } @Test // DATAJDBC-462 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) - public void resavingAnUnversionedEntity() { + void resavingAnUnversionedEntity() { LegoSet legoSet = new LegoSet(); @@ -879,7 +879,7 @@ public void resavingAnUnversionedEntity() { @Test // DATAJDBC-637 @EnabledOnFeature(SUPPORTS_NANOSECOND_PRECISION) - public void saveAndLoadDateTimeWithFullPrecision() { + void saveAndLoadDateTimeWithFullPrecision() { WithLocalDateTime entity = new WithLocalDateTime(); entity.id = 23L; @@ -893,7 +893,7 @@ public void saveAndLoadDateTimeWithFullPrecision() { } @Test // DATAJDBC-637 - public void saveAndLoadDateTimeWithMicrosecondPrecision() { + void saveAndLoadDateTimeWithMicrosecondPrecision() { WithLocalDateTime entity = new WithLocalDateTime(); entity.id = 23L; @@ -907,7 +907,7 @@ public void saveAndLoadDateTimeWithMicrosecondPrecision() { } @Test // GH-777 - public void insertWithIdOnly() { + void insertWithIdOnly() { WithIdOnly entity = new WithIdOnly(); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java index 7983cc99c6..8e5186269d 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/EntityRowMapperUnitTests.java @@ -78,10 +78,10 @@ */ public class EntityRowMapperUnitTests { - public static final long ID_FOR_ENTITY_REFERENCING_MAP = 42L; - public static final long ID_FOR_ENTITY_REFERENCING_LIST = 4711L; - public static final long ID_FOR_ENTITY_NOT_REFERENCING_MAP = 23L; - public static final NamingStrategy X_APPENDING_NAMINGSTRATEGY = new NamingStrategy() { + static final long ID_FOR_ENTITY_REFERENCING_MAP = 42L; + static final long ID_FOR_ENTITY_REFERENCING_LIST = 4711L; + static final long ID_FOR_ENTITY_NOT_REFERENCING_MAP = 23L; + static final NamingStrategy X_APPENDING_NAMINGSTRATEGY = new NamingStrategy() { @Override public String getColumnName(RelationalPersistentProperty property) { return NamingStrategy.super.getColumnName(property).concat("x"); @@ -89,7 +89,7 @@ public String getColumnName(RelationalPersistentProperty property) { }; @Test // DATAJDBC-113 - public void simpleEntitiesGetProperlyExtracted() throws SQLException { + void simpleEntitiesGetProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -104,7 +104,7 @@ public void simpleEntitiesGetProperlyExtracted() throws SQLException { } @Test // DATAJDBC-181 - public void namingStrategyGetsHonored() throws SQLException { + void namingStrategyGetsHonored() throws SQLException { ResultSet rs = mockResultSet(asList("IDX", "NAMEX"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -119,7 +119,7 @@ public void namingStrategyGetsHonored() throws SQLException { } @Test // DATAJDBC-181 - public void namingStrategyGetsHonoredForConstructor() throws SQLException { + void namingStrategyGetsHonoredForConstructor() throws SQLException { ResultSet rs = mockResultSet(asList("IDX", "NAMEX"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -134,7 +134,7 @@ public void namingStrategyGetsHonoredForConstructor() throws SQLException { } @Test // DATAJDBC-427 - public void simpleWithReferenceGetProperlyExtracted() throws SQLException { + void simpleWithReferenceGetProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "TRIVIAL_ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 100L); @@ -149,7 +149,7 @@ public void simpleWithReferenceGetProperlyExtracted() throws SQLException { } @Test // DATAJDBC-113 - public void simpleOneToOneGetsProperlyExtracted() throws SQLException { + void simpleOneToOneGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "CHILD_ID", "CHILD_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24L, "beta"); @@ -164,7 +164,7 @@ public void simpleOneToOneGetsProperlyExtracted() throws SQLException { } @Test // DATAJDBC-286 - public void immutableOneToOneGetsProperlyExtracted() throws SQLException { + void immutableOneToOneGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "CHILD_ID", "CHILD_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24L, "beta"); @@ -179,7 +179,7 @@ public void immutableOneToOneGetsProperlyExtracted() throws SQLException { } @Test // DATAJDBC-427 - public void immutableWithReferenceGetsProperlyExtracted() throws SQLException { + void immutableWithReferenceGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "TRIVIAL_ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 100L); @@ -195,7 +195,7 @@ public void immutableWithReferenceGetsProperlyExtracted() throws SQLException { // TODO add additional test for multilevel embeddables @Test // DATAJDBC-111 - public void simpleEmbeddedGetsProperlyExtracted() throws SQLException { + void simpleEmbeddedGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "PREFIX_ID", "PREFIX_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24L, "beta"); @@ -210,7 +210,7 @@ public void simpleEmbeddedGetsProperlyExtracted() throws SQLException { } @Test // DATAJDBC-113 - public void collectionReferenceGetsLoadedWithAdditionalSelect() throws SQLException { + void collectionReferenceGetsLoadedWithAdditionalSelect() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -225,7 +225,7 @@ public void collectionReferenceGetsLoadedWithAdditionalSelect() throws SQLExcept } @Test // DATAJDBC-131 - public void mapReferenceGetsLoadedWithAdditionalSelect() throws SQLException { + void mapReferenceGetsLoadedWithAdditionalSelect() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME"), // ID_FOR_ENTITY_REFERENCING_MAP, "alpha"); @@ -240,7 +240,7 @@ public void mapReferenceGetsLoadedWithAdditionalSelect() throws SQLException { } @Test // DATAJDBC-130 - public void listReferenceGetsLoadedWithAdditionalSelect() throws SQLException { + void listReferenceGetsLoadedWithAdditionalSelect() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME"), // ID_FOR_ENTITY_REFERENCING_LIST, "alpha"); @@ -255,7 +255,7 @@ public void listReferenceGetsLoadedWithAdditionalSelect() throws SQLException { } @Test // DATAJDBC-252 - public void doesNotTryToSetPropertiesThatAreSetViaConstructor() throws SQLException { + void doesNotTryToSetPropertiesThatAreSetViaConstructor() throws SQLException { ResultSet rs = mockResultSet(singletonList("VALUE"), // "value-from-resultSet"); @@ -268,7 +268,7 @@ public void doesNotTryToSetPropertiesThatAreSetViaConstructor() throws SQLExcept } @Test // DATAJDBC-252 - public void handlesMixedProperties() throws SQLException { + void handlesMixedProperties() throws SQLException { ResultSet rs = mockResultSet(asList("ONE", "TWO", "THREE"), // "111", "222", "333"); @@ -282,7 +282,7 @@ public void handlesMixedProperties() throws SQLException { } @Test // DATAJDBC-359 - public void chainedEntitiesWithoutId() throws SQLException { + void chainedEntitiesWithoutId() throws SQLException { // @formatter:off Fixture fixture = this. buildFixture() // @@ -318,7 +318,7 @@ public void chainedEntitiesWithoutId() throws SQLException { } @Test // DATAJDBC-370 - public void simpleNullableImmutableEmbeddedGetsProperlyExtracted() throws SQLException { + void simpleNullableImmutableEmbeddedGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "ru'Ha'", "Alfred"); @@ -334,7 +334,7 @@ public void simpleNullableImmutableEmbeddedGetsProperlyExtracted() throws SQLExc } @Test // DATAJDBC-374 - public void simpleEmptyImmutableEmbeddedGetsProperlyExtracted() throws SQLException { + void simpleEmptyImmutableEmbeddedGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, null, null); @@ -349,7 +349,7 @@ public void simpleEmptyImmutableEmbeddedGetsProperlyExtracted() throws SQLExcept } @Test // DATAJDBC-370 - public void simplePrimitiveImmutableEmbeddedGetsProperlyExtracted() throws SQLException { + void simplePrimitiveImmutableEmbeddedGetsProperlyExtracted() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, 24); @@ -365,7 +365,7 @@ public void simplePrimitiveImmutableEmbeddedGetsProperlyExtracted() throws SQLEx } @Test // DATAJDBC-370 - public void simpleImmutableEmbeddedShouldBeNullIfAllOfTheEmbeddableAreNull() throws SQLException { + void simpleImmutableEmbeddedShouldBeNullIfAllOfTheEmbeddableAreNull() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, null, null); @@ -381,7 +381,7 @@ public void simpleImmutableEmbeddedShouldBeNullIfAllOfTheEmbeddableAreNull() thr } @Test // DATAJDBC-370 - public void embeddedShouldBeNullWhenFieldsAreNull() throws SQLException { + void embeddedShouldBeNullWhenFieldsAreNull() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "PREFIX_ID", "PREFIX_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", null, null); @@ -396,7 +396,7 @@ public void embeddedShouldBeNullWhenFieldsAreNull() throws SQLException { } @Test // DATAJDBC-370 - public void embeddedShouldNotBeNullWhenAtLeastOneFieldIsNotNull() throws SQLException { + void embeddedShouldNotBeNullWhenAtLeastOneFieldIsNotNull() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "PREFIX_ID", "PREFIX_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24, null); @@ -411,7 +411,7 @@ public void embeddedShouldNotBeNullWhenAtLeastOneFieldIsNotNull() throws SQLExce } @Test // DATAJDBC-370 - public void primitiveEmbeddedShouldBeNullWhenNoValuePresent() throws SQLException { + void primitiveEmbeddedShouldBeNullWhenNoValuePresent() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, null); @@ -427,7 +427,7 @@ public void primitiveEmbeddedShouldBeNullWhenNoValuePresent() throws SQLExceptio } @Test // DATAJDBC-370 - public void deepNestedEmbeddable() throws SQLException { + void deepNestedEmbeddable() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "LEVEL0", "LEVEL1_VALUE", "LEVEL1_LEVEL2_VALUE", "LEVEL1_LEVEL2_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "0", "1", "2", "Rumpelstilzchen"); @@ -442,7 +442,7 @@ public void deepNestedEmbeddable() throws SQLException { } @Test // DATAJDBC-341 - public void missingValueForObjectGetsMappedToZero() throws SQLException { + void missingValueForObjectGetsMappedToZero() throws SQLException { ResultSet rs = mockResultSet(singletonList("id"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP); @@ -457,7 +457,7 @@ public void missingValueForObjectGetsMappedToZero() throws SQLException { } @Test // DATAJDBC-341 - public void missingValueForConstructorArgCausesException() throws SQLException { + void missingValueForConstructorArgCausesException() throws SQLException { ResultSet rs = mockResultSet(singletonList("id"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP); @@ -470,7 +470,7 @@ public void missingValueForConstructorArgCausesException() throws SQLException { } @Test // DATAJDBC-341 - public void missingColumnForPrimitiveGetsMappedToZero() throws SQLException { + void missingColumnForPrimitiveGetsMappedToZero() throws SQLException { ResultSet rs = mockResultSet(singletonList("id"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP); @@ -486,7 +486,7 @@ public void missingColumnForPrimitiveGetsMappedToZero() throws SQLException { } @Test // DATAJDBC-341 - public void columnNamesAreCaseInsensitive() throws SQLException { + void columnNamesAreCaseInsensitive() throws SQLException { ResultSet rs = mockResultSet(asList("id", "name"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -501,7 +501,7 @@ public void columnNamesAreCaseInsensitive() throws SQLException { } @Test // DATAJDBC-341 - public void immutableEmbeddedWithAllColumnsMissingShouldBeNull() throws SQLException { + void immutableEmbeddedWithAllColumnsMissingShouldBeNull() throws SQLException { ResultSet rs = mockResultSet(asList("ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP); @@ -517,7 +517,7 @@ public void immutableEmbeddedWithAllColumnsMissingShouldBeNull() throws SQLExcep } @Test // DATAJDBC-341 - public void immutableEmbeddedWithSomeColumnsMissingShouldNotBeEmpty() throws SQLException { + void immutableEmbeddedWithSomeColumnsMissingShouldNotBeEmpty() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "some value"); @@ -529,7 +529,7 @@ public void immutableEmbeddedWithSomeColumnsMissingShouldNotBeEmpty() throws SQL } @Test // DATAJDBC-341 - public void immutableEmbeddedWithSomeColumnsMissingAndSomeNullShouldBeNull() throws SQLException { + void immutableEmbeddedWithSomeColumnsMissingAndSomeNullShouldBeNull() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "VALUE"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, null); @@ -545,7 +545,7 @@ public void immutableEmbeddedWithSomeColumnsMissingAndSomeNullShouldBeNull() thr } @Test // DATAJDBC-341 - public void embeddedShouldBeNullWhenAllFieldsAreMissing() throws SQLException { + void embeddedShouldBeNullWhenAllFieldsAreMissing() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha"); @@ -560,7 +560,7 @@ public void embeddedShouldBeNullWhenAllFieldsAreMissing() throws SQLException { } @Test // DATAJDBC-341 - public void missingColumnsInEmbeddedShouldBeUnset() throws SQLException { + void missingColumnsInEmbeddedShouldBeUnset() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "PREFIX_ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24); @@ -575,7 +575,7 @@ public void missingColumnsInEmbeddedShouldBeUnset() throws SQLException { } @Test // DATAJDBC-341 - public void primitiveEmbeddedShouldBeNullWhenAllColumnsAreMissing() throws SQLException { + void primitiveEmbeddedShouldBeNullWhenAllColumnsAreMissing() throws SQLException { ResultSet rs = mockResultSet(asList("ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP); @@ -591,7 +591,7 @@ public void primitiveEmbeddedShouldBeNullWhenAllColumnsAreMissing() throws SQLEx } @Test // DATAJDBC-341 - public void oneToOneWithMissingColumnResultsInNullProperty() throws SQLException { + void oneToOneWithMissingColumnResultsInNullProperty() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "CHILD_ID"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24L); @@ -606,7 +606,7 @@ public void oneToOneWithMissingColumnResultsInNullProperty() throws SQLException } @Test // DATAJDBC-341 - public void oneToOneWithMissingIdColumnResultsInNullProperty() throws SQLException { + void oneToOneWithMissingIdColumnResultsInNullProperty() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "CHILD_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", "Alfred"); @@ -618,7 +618,7 @@ public void oneToOneWithMissingIdColumnResultsInNullProperty() throws SQLExcepti } @Test // DATAJDBC-341 - public void immutableOneToOneWithIdMissingColumnResultsInNullReference() throws SQLException { + void immutableOneToOneWithIdMissingColumnResultsInNullReference() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "NAME", "CHILD_NAME"), // ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", "Alfred"); @@ -632,7 +632,7 @@ public void immutableOneToOneWithIdMissingColumnResultsInNullReference() throws } @Test // DATAJDBC-508 - public void materializesObjectWithAtValue() throws SQLException { + void materializesObjectWithAtValue() throws SQLException { ResultSet rs = mockResultSet(asList("ID", "FIRST_NAME"), // 123L, "Hello World"); @@ -939,7 +939,7 @@ private static class ResultSetAnswer implements Answer { private final List> values; private int index = -1; - public ResultSetAnswer(List names, List> values) { + ResultSetAnswer(List names, List> values) { this.names = names; this.values = values; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java index d761aba0fb..0bfcdc7386 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java @@ -242,6 +242,7 @@ private Object getPotentiallyConvertedSimpleWrite(Object value) { @Nullable @SuppressWarnings({ "rawtypes", "unchecked" }) private Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation type) { + Class target = type.getType(); if (ClassUtils.isAssignableValue(target, value)) { return value; diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java index 5499b83b52..5d3ed28835 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/BasicRelationalConverterUnitTests.java @@ -17,6 +17,9 @@ import static org.assertj.core.api.Assertions.*; +import lombok.Data; +import lombok.Value; + import java.util.Arrays; import java.util.List; import java.util.Set; @@ -33,16 +36,13 @@ import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; -import lombok.Data; -import lombok.Value; - /** * Unit tests for {@link BasicRelationalConverter}. * * @author Mark Paluch * @author Chirag Tailor */ -public class BasicRelationalConverterUnitTests { +class BasicRelationalConverterUnitTests { RelationalMappingContext context = new RelationalMappingContext(); RelationalConverter converter; @@ -61,7 +61,7 @@ public void before() throws Exception { @Test // DATAJDBC-235 @SuppressWarnings("unchecked") - public void shouldUseConvertingPropertyAccessor() { + void shouldUseConvertingPropertyAccessor() { RelationalPersistentEntity entity = (RelationalPersistentEntity) context .getRequiredPersistentEntity(MyEntity.class); @@ -76,7 +76,7 @@ public void shouldUseConvertingPropertyAccessor() { } @Test // DATAJDBC-235 - public void shouldConvertEnumToString() { + void shouldConvertEnumToString() { Object result = converter.writeValue(MyEnum.ON, ClassTypeInformation.from(String.class)); @@ -84,7 +84,7 @@ public void shouldConvertEnumToString() { } @Test // DATAJDBC-235 - public void shouldConvertStringToEnum() { + void shouldConvertStringToEnum() { Object result = converter.readValue("OFF", ClassTypeInformation.from(MyEnum.class)); @@ -93,15 +93,17 @@ public void shouldConvertStringToEnum() { @Test // GH-1046 void shouldConvertArrayElementsToTargetElementType() throws NoSuchMethodException { - TypeInformation typeInformation = ClassTypeInformation.fromReturnTypeOf(EntityWithArray.class.getMethod("getFloats")); - Double[] value = {1.2d, 1.3d, 1.4d}; + + TypeInformation typeInformation = ClassTypeInformation + .fromReturnTypeOf(EntityWithArray.class.getMethod("getFloats")); + Double[] value = { 1.2d, 1.3d, 1.4d }; Object result = converter.readValue(value, typeInformation); assertThat(result).isEqualTo(Arrays.asList(1.2f, 1.3f, 1.4f)); } @Test // DATAJDBC-235 @SuppressWarnings("unchecked") - public void shouldCreateInstance() { + void shouldCreateInstance() { RelationalPersistentEntity entity = (RelationalPersistentEntity) context .getRequiredPersistentEntity(WithConstructorCreation.class); @@ -112,7 +114,7 @@ public void shouldCreateInstance() { } @Test // DATAJDBC-516 - public void shouldConsiderWriteConverter() { + void shouldConsiderWriteConverter() { Object result = converter.writeValue(new MyValue("hello-world"), ClassTypeInformation.from(MyValue.class)); @@ -120,7 +122,7 @@ public void shouldConsiderWriteConverter() { } @Test // DATAJDBC-516 - public void shouldConsiderReadConverter() { + void shouldConsiderReadConverter() { Object result = converter.readValue("hello-world", ClassTypeInformation.from(MyValue.class)); From 0dcf12c83cc34e2252f86365f11336723bdd86ce Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Mon, 31 Jan 2022 13:22:26 -0600 Subject: [PATCH 12/51] Externalize build properties. See #1151. --- Jenkinsfile | 20 +++++++++++++------- ci/pipeline.properties | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 ci/pipeline.properties diff --git a/Jenkinsfile b/Jenkinsfile index 1d8465c17d..87abc16251 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,3 +1,9 @@ +def p = [:] +node { + checkout scm + p = readProperties interpolate: true, file: 'ci/pipeline.properties' +} + pipeline { agent none @@ -12,7 +18,7 @@ pipeline { } stages { - stage("test: baseline (jdk8)") { + stage("test: baseline (main)") { when { beforeAgent(true) anyOf { @@ -33,7 +39,7 @@ pipeline { steps { script { docker.withRegistry('', 'hub.docker.com-springbuildmaster') { - docker.image('adoptopenjdk/openjdk8:latest').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') { + docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,all-dbs ci/test.sh" sh "ci/clean.sh" @@ -52,7 +58,7 @@ pipeline { } } parallel { - stage("test: baseline (jdk11)") { + stage("test: baseline (next)") { agent { label 'data' } @@ -66,7 +72,7 @@ pipeline { steps { script { docker.withRegistry('', 'hub.docker.com-springbuildmaster') { - docker.image('adoptopenjdk/openjdk11:latest').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') { + docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,java11 ci/test.sh" sh "ci/clean.sh" @@ -76,7 +82,7 @@ pipeline { } } - stage("test: baseline (jdk17)") { + stage("test: baseline (LTS)") { agent { label 'data' } @@ -90,7 +96,7 @@ pipeline { steps { script { docker.withRegistry('', 'hub.docker.com-springbuildmaster') { - docker.image('openjdk:17-bullseye').inside('-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home') { + docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,java11 ci/test.sh" sh "ci/clean.sh" @@ -122,7 +128,7 @@ pipeline { steps { script { docker.withRegistry('', 'hub.docker.com-springbuildmaster') { - docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') { + docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) { sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-jdbc-non-root ' + '-Dartifactory.server=https://repo.spring.io ' + "-Dartifactory.username=${ARTIFACTORY_USR} " + diff --git a/ci/pipeline.properties b/ci/pipeline.properties new file mode 100644 index 0000000000..5d91102d25 --- /dev/null +++ b/ci/pipeline.properties @@ -0,0 +1,24 @@ +# Java versions +java.main.tag=8u312-b07-jdk +java.next.tag=11.0.13_8-jdk +java.lts.tag=17.0.1_12-jdk + +# Docker container images - standard +docker.java.main.image=eclipse-temurin:${java.main.tag} +docker.java.next.image=eclipse-temurin:${java.next.tag} +docker.java.lts.image=eclipse-temurin:${java.lts.tag} + +# Supported versions of MongoDB +docker.mongodb.4.0.version=4.0.23 +docker.mongodb.4.4.version=4.4.4 +docker.mongodb.5.0.version=5.0.3 + +# Supported versions of Redis +docker.redis.6.version=6.2.4 + +# Supported versions of Cassandra +docker.cassandra.3.version=3.11.10 + +# Docker environment settings +docker.java.inside.basic=-v $HOME:/tmp/jenkins-home +docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home From a132d432e8de9fc108bc53f4065cab09c7d9a1a2 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 2 Feb 2022 15:29:57 +0100 Subject: [PATCH 13/51] Render windowing functions without arguments correctly. Closes #1153 See #1019 --- .../core/sql/render/SimpleFunctionVisitor.java | 7 ++----- .../core/sql/render/SelectRendererUnitTests.java | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java index 1620c4b7f1..1f76386936 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java @@ -30,7 +30,6 @@ class SimpleFunctionVisitor extends TypedSingleConditionRenderSupport Date: Wed, 24 Nov 2021 16:45:58 +0100 Subject: [PATCH 14/51] Replaces java.sql.Types constants with java.sql.SQLType values. java.sql.Types constants are int values and therefore make it tedious to read and debug the code. SQLType values are mostly enum constants which are much nicer to use. Original pull request #1142 --- .../jdbc/core/convert/BasicJdbcConverter.java | 22 ++++- .../convert/DefaultDataAccessStrategy.java | 14 +-- .../core/convert/DefaultJdbcTypeFactory.java | 4 +- .../data/jdbc/core/convert/JdbcConverter.java | 21 +++- .../data/jdbc/core/convert/JdbcValue.java | 5 +- .../data/jdbc/core/mapping/JdbcValue.java | 9 +- .../jdbc/repository/query/QueryMapper.java | 52 +++++----- .../query/StringBasedJdbcQuery.java | 6 +- .../data/jdbc/support/JdbcUtil.java | 99 +++++++++++++------ .../convert/BasicJdbcConverterUnitTests.java | 2 +- .../data/jdbc/support/JdbcUtilTests.java | 4 +- 11 files changed, 157 insertions(+), 81 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java index 6114f5b9ca..0898c0ca70 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java @@ -19,6 +19,7 @@ import java.sql.JDBCType; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.SQLType; import java.util.Map; import java.util.Optional; @@ -171,10 +172,15 @@ private Class getReferenceColumnType(RelationalPersistentProperty property) { * @see org.springframework.data.jdbc.core.convert.JdbcConverter#getSqlType(org.springframework.data.relational.core.mapping.RelationalPersistentProperty) */ @Override + public SQLType getTargetSqlType(RelationalPersistentProperty property) { + return JdbcUtil.targetSqlTypeFor(getColumnType(property)); + } + + @Override + @Deprecated public int getSqlType(RelationalPersistentProperty property) { return JdbcUtil.sqlTypeFor(getColumnType(property)); } - /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.convert.JdbcConverter#getColumnType(org.springframework.data.relational.core.mapping.RelationalPersistentProperty) @@ -275,12 +281,19 @@ private boolean canWriteAsJdbcValue(@Nullable Object value) { return customWriteTarget.isPresent() && customWriteTarget.get().isAssignableFrom(JdbcValue.class); } - /* + @Override + @Deprecated + public JdbcValue writeJdbcValue(@Nullable Object value, Class columnType, int sqlType) { + return writeJdbcValue(value, columnType, JdbcUtil.jdbcTypeFor(sqlType)); + } + + + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.convert.JdbcConverter#writeValue(java.lang.Object, java.lang.Class, int) */ @Override - public JdbcValue writeJdbcValue(@Nullable Object value, Class columnType, int sqlType) { + public JdbcValue writeJdbcValue(@Nullable Object value, Class columnType, SQLType sqlType) { JdbcValue jdbcValue = tryToConvertToJdbcValue(value); if (jdbcValue != null) { @@ -290,7 +303,8 @@ public JdbcValue writeJdbcValue(@Nullable Object value, Class columnType, int Object convertedValue = writeValue(value, ClassTypeInformation.from(columnType)); if (convertedValue == null || !convertedValue.getClass().isArray()) { - return JdbcValue.of(convertedValue, JdbcUtil.jdbcTypeFor(sqlType)); + + return JdbcValue.of(convertedValue, sqlType); } Class componentType = convertedValue.getClass().getComponentType(); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index a5f1eab953..151c77027a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -17,8 +17,8 @@ import static org.springframework.data.jdbc.core.convert.SqlGenerator.*; -import java.sql.JDBCType; import java.sql.ResultSet; +import java.sql.SQLType; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -546,17 +546,17 @@ private IdentifierProcessing getIdentifierProcessing() { private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSource, RelationalPersistentProperty property, @Nullable Object value, SqlIdentifier name) { - addConvertedValue(parameterSource, value, name, converter.getColumnType(property), converter.getSqlType(property)); + addConvertedValue(parameterSource, value, name, converter.getColumnType(property), converter.getTargetSqlType(property)); } private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSource, SqlIdentifier name, Object value, Class javaType) { - addConvertedValue(parameterSource, value, name, javaType, JdbcUtil.sqlTypeFor(javaType)); + addConvertedValue(parameterSource, value, name, javaType, JdbcUtil.targetSqlTypeFor(javaType)); } private void addConvertedValue(SqlIdentifierParameterSource parameterSource, @Nullable Object value, - SqlIdentifier paramName, Class javaType, int sqlType) { + SqlIdentifier paramName, Class javaType, SQLType sqlType) { JdbcValue jdbcValue = converter.writeJdbcValue( // value, // @@ -567,7 +567,7 @@ private void addConvertedValue(SqlIdentifierParameterSource parameterSource, @Nu parameterSource.addValue( // paramName, // jdbcValue.getValue(), // - JdbcUtil.sqlTypeFor(jdbcValue.getJdbcType())); + jdbcValue.getJdbcType().getVendorTypeNumber()); } private void addConvertedPropertyValuesAsList(SqlIdentifierParameterSource parameterSource, @@ -578,7 +578,7 @@ private void addConvertedPropertyValuesAsList(SqlIdentifierParameterSource param for (Object id : values) { Class columnType = converter.getColumnType(property); - int sqlType = converter.getSqlType(property); + SQLType sqlType = converter.getTargetSqlType(property); jdbcValue = converter.writeJdbcValue(id, columnType, sqlType); convertedIds.add(jdbcValue.getValue()); @@ -586,7 +586,7 @@ private void addConvertedPropertyValuesAsList(SqlIdentifierParameterSource param Assert.state(jdbcValue != null, "JdbcValue must be not null at this point. Please report this as a bug."); - JDBCType jdbcType = jdbcValue.getJdbcType(); + SQLType jdbcType = jdbcValue.getJdbcType(); int typeNumber = jdbcType == null ? JdbcUtils.TYPE_UNKNOWN : jdbcType.getVendorTypeNumber(); parameterSource.addValue(paramName, convertedIds, typeNumber); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java index c70287d1ba..09f5627f3e 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java @@ -16,7 +16,7 @@ package org.springframework.data.jdbc.core.convert; import java.sql.Array; -import java.sql.JDBCType; +import java.sql.SQLType; import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns; import org.springframework.data.jdbc.support.JdbcUtil; @@ -68,7 +68,7 @@ public Array createArray(Object[] value) { Class componentType = arrayColumns.getArrayType(value.getClass()); - JDBCType jdbcType = JdbcUtil.jdbcTypeFor(componentType); + SQLType jdbcType = JdbcUtil.targetSqlTypeFor(componentType); Assert.notNull(jdbcType, () -> String.format("Couldn't determine JDBCType for %s", componentType)); String typeName = arrayColumns.getArrayTypeName(jdbcType); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcConverter.java index 31fc2e3726..6f4f1635ad 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcConverter.java @@ -16,6 +16,7 @@ package org.springframework.data.jdbc.core.convert; import java.sql.ResultSet; +import java.sql.SQLType; import org.springframework.data.jdbc.core.mapping.JdbcValue; import org.springframework.data.relational.core.conversion.RelationalConverter; @@ -39,12 +40,24 @@ public interface JdbcConverter extends RelationalConverter { * to JDBC parameters. * * @param value a value as it is used in the object model. May be {@code null}. - * @param type {@link TypeInformation} into which the value is to be converted. Must not be {@code null}. + * @param type {@literal Class} into which the value is to be converted. Must not be {@code null}. * @param sqlType the type constant from {@link java.sql.Types} to be used if non is specified by a converter. * @return The converted value wrapped in a {@link JdbcValue}. Guaranteed to be not {@literal null}. */ JdbcValue writeJdbcValue(@Nullable Object value, Class type, int sqlType); + /** + * Convert a property value into a {@link JdbcValue} that contains the converted value and information how to bind it + * to JDBC parameters. + * + * @param value a value as it is used in the object model. May be {@code null}. + * @param type {@literal Class} into which the value is to be converted. Must not be {@code null}. + * @param sqlType the {@link SQLType} to be used if non is specified by a converter. + * @return The converted value wrapped in a {@link JdbcValue}. Guaranteed to be not {@literal null}. + * @since 2.4 + */ + JdbcValue writeJdbcValue(@Nullable Object value, Class type, SQLType sqlType); + /** * Read the current row from {@link ResultSet} to an {@link RelationalPersistentEntity#getType() entity}. * @@ -73,7 +86,7 @@ public interface JdbcConverter extends RelationalConverter { * top-level array type (e.g. {@code String[][]} returns {@code String[]}). * * @return a {@link Class} that is suitable for usage with JDBC drivers. - * @see org.springframework.data.jdbc.support.JdbcUtil#sqlTypeFor(Class) + * @see org.springframework.data.jdbc.support.JdbcUtil#targetSqlTypeFor(Class) * @since 2.0 */ Class getColumnType(RelationalPersistentProperty property); @@ -85,5 +98,9 @@ public interface JdbcConverter extends RelationalConverter { * @see java.sql.Types * @since 2.0 */ + SQLType getTargetSqlType(RelationalPersistentProperty property); + + @Deprecated int getSqlType(RelationalPersistentProperty property); + } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcValue.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcValue.java index c8c37b5323..e174ef44ef 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcValue.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcValue.java @@ -16,6 +16,7 @@ package org.springframework.data.jdbc.core.convert; import java.sql.JDBCType; +import java.sql.SQLType; import java.util.Objects; import org.springframework.lang.Nullable; @@ -32,11 +33,11 @@ @Deprecated public final class JdbcValue extends org.springframework.data.jdbc.core.mapping.JdbcValue { - private JdbcValue(@Nullable Object value, @Nullable JDBCType jdbcType) { + private JdbcValue(@Nullable Object value, @Nullable SQLType jdbcType) { super(value, jdbcType); } - public static JdbcValue of(@Nullable Object value, @Nullable JDBCType jdbcType) { + public static JdbcValue of(@Nullable Object value, @Nullable SQLType jdbcType) { return new JdbcValue(value, jdbcType); } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcValue.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcValue.java index 8e0dd48ba0..91f50417fd 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcValue.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcValue.java @@ -16,6 +16,7 @@ package org.springframework.data.jdbc.core.mapping; import java.sql.JDBCType; +import java.sql.SQLType; import java.util.Objects; import org.springframework.lang.Nullable; @@ -31,15 +32,15 @@ public class JdbcValue { private final Object value; - private final JDBCType jdbcType; + private final SQLType jdbcType; - protected JdbcValue(@Nullable Object value, @Nullable JDBCType jdbcType) { + protected JdbcValue(@Nullable Object value, @Nullable SQLType jdbcType) { this.value = value; this.jdbcType = jdbcType; } - public static JdbcValue of(@Nullable Object value, @Nullable JDBCType jdbcType) { + public static JdbcValue of(@Nullable Object value, @Nullable SQLType jdbcType) { return new JdbcValue(value, jdbcType); } @@ -49,7 +50,7 @@ public Object getValue() { } @Nullable - public JDBCType getJdbcType() { + public SQLType getJdbcType() { return this.jdbcType; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java index 09b1138c21..33a3a4fad9 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java @@ -16,7 +16,7 @@ package org.springframework.data.jdbc.repository.query; import java.sql.JDBCType; -import java.sql.Types; +import java.sql.SQLType; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -27,6 +27,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.mapping.JdbcValue; +import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PropertyPath; @@ -45,7 +46,6 @@ import org.springframework.data.util.Pair; import org.springframework.data.util.TypeInformation; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.support.JdbcUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -279,7 +279,7 @@ private Condition mapCondition(CriteriaDefinition criteria, MapSqlParameterSourc TypeInformation actualType = propertyField.getTypeHint().getRequiredActualType(); Column column = table.column(propertyField.getMappedColumnName()); Object mappedValue; - int sqlType; + SQLType sqlType; if (criteria.getValue() instanceof JdbcValue) { @@ -302,7 +302,7 @@ private Condition mapCondition(CriteriaDefinition criteria, MapSqlParameterSourc RelationalPersistentProperty property = ((MetadataBackedField) propertyField).property; JdbcValue jdbcValue = convertToJdbcValue(property, criteria.getValue()); mappedValue = jdbcValue.getValue(); - sqlType = jdbcValue.getJdbcType() != null ? jdbcValue.getJdbcType().getVendorTypeNumber() + sqlType = jdbcValue.getJdbcType() != null ? jdbcValue.getJdbcType() : propertyField.getSqlType(); } else { @@ -339,7 +339,7 @@ private JdbcValue convertToJdbcValue(RelationalPersistentProperty property, @Nul if (value instanceof Iterable) { List mapped = new ArrayList<>(); - JDBCType jdbcType = null; + SQLType jdbcType = null; for (Object o : (Iterable) value) { @@ -358,7 +358,7 @@ private JdbcValue convertToJdbcValue(RelationalPersistentProperty property, @Nul Object[] valueAsArray = (Object[]) value; Object[] mappedValueArray = new Object[valueAsArray.length]; - JDBCType jdbcType = null; + SQLType jdbcType = null; for (int i = 0; i < valueAsArray.length; i++) { @@ -389,7 +389,7 @@ private JdbcValue getWriteValue(RelationalPersistentProperty property, Object va return converter.writeJdbcValue( // value, // converter.getColumnType(property), // - converter.getSqlType(property) // + converter.getTargetSqlType(property) // ); } @@ -410,7 +410,7 @@ private Condition mapEmbeddedObjectCondition(CriteriaDefinition criteria, MapSql SqlIdentifier sqlIdentifier = nestedProperty.getColumnName().transform(prefix::concat); Object mappedNestedValue = convertValue(embeddedAccessor.getProperty(nestedProperty), nestedProperty.getTypeInformation()); - int sqlType = converter.getSqlType(nestedProperty); + SQLType sqlType = converter.getTargetSqlType(nestedProperty); Condition mappedCondition = createCondition(table.column(sqlIdentifier), mappedNestedValue, sqlType, parameterSource, criteria.getComparator(), criteria.isIgnoreCase()); @@ -481,8 +481,8 @@ protected MappingContext, RelationalPers return this.mappingContext; } - private Condition createCondition(Column column, @Nullable Object mappedValue, int sqlType, - MapSqlParameterSource parameterSource, Comparator comparator, boolean ignoreCase) { + private Condition createCondition(Column column, @Nullable Object mappedValue, SQLType sqlType, + MapSqlParameterSource parameterSource, Comparator comparator, boolean ignoreCase) { if (comparator.equals(Comparator.IS_NULL)) { return column.isNull(); @@ -505,7 +505,7 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, i } Expression columnExpression = column; - if (ignoreCase && (sqlType == Types.VARCHAR || sqlType == Types.NVARCHAR)) { + if (ignoreCase && (sqlType == JDBCType.VARCHAR || sqlType == JDBCType.NVARCHAR)) { columnExpression = Functions.upper(column); } @@ -593,7 +593,7 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, i private Expression bindBoolean(Column column, MapSqlParameterSource parameterSource, boolean value) { Object converted = converter.writeValue(value, ClassTypeInformation.OBJECT); - return bind(converted, Types.BIT, parameterSource, column.getName().getReference()); + return bind(converted, JDBCType.BIT, parameterSource, column.getName().getReference()); } Field createPropertyField(@Nullable RelationalPersistentEntity entity, SqlIdentifier key) { @@ -605,30 +605,30 @@ Field createPropertyField(@Nullable RelationalPersistentEntity entity, SqlIde return entity == null ? new Field(key) : new MetadataBackedField(key, entity, mappingContext, converter); } - int getTypeHint(@Nullable Object mappedValue, Class propertyType, JdbcValue settableValue) { + SQLType getTypeHint(@Nullable Object mappedValue, Class propertyType, JdbcValue settableValue) { if (mappedValue == null || propertyType.equals(Object.class)) { - return JdbcUtils.TYPE_UNKNOWN; + return JdbcUtil.TYPE_UNKNOWN; } if (mappedValue.getClass().equals(settableValue.getValue().getClass())) { - return JdbcUtils.TYPE_UNKNOWN; + return JdbcUtil.TYPE_UNKNOWN; } - return settableValue.getJdbcType().getVendorTypeNumber(); + return settableValue.getJdbcType(); } - private Expression bind(@Nullable Object mappedValue, int sqlType, MapSqlParameterSource parameterSource, - String name) { + private Expression bind(@Nullable Object mappedValue, SQLType sqlType, MapSqlParameterSource parameterSource, + String name) { return bind(mappedValue, sqlType, parameterSource, name, false); } - private Expression bind(@Nullable Object mappedValue, int sqlType, MapSqlParameterSource parameterSource, String name, - boolean ignoreCase) { + private Expression bind(@Nullable Object mappedValue, SQLType sqlType, MapSqlParameterSource parameterSource, String name, + boolean ignoreCase) { String uniqueName = getUniqueName(parameterSource, name); - parameterSource.addValue(uniqueName, mappedValue, sqlType); + parameterSource.addValue(uniqueName, mappedValue, sqlType.getVendorTypeNumber()); return ignoreCase ? Functions.upper(SQL.bindMarker(":" + uniqueName)) : SQL.bindMarker(":" + uniqueName); } @@ -686,8 +686,8 @@ public TypeInformation getTypeHint() { return ClassTypeInformation.OBJECT; } - public int getSqlType() { - return JdbcUtils.TYPE_UNKNOWN; + public SQLType getSqlType() { + return JdbcUtil.TYPE_UNKNOWN; } } @@ -701,7 +701,7 @@ protected static class MetadataBackedField extends Field { private final RelationalPersistentProperty property; private final @Nullable PersistentPropertyPath path; private final boolean embedded; - private final int sqlType; + private final SQLType sqlType; /** * Creates a new {@link MetadataBackedField} with the given name, {@link RelationalPersistentEntity} and @@ -741,7 +741,7 @@ protected MetadataBackedField(SqlIdentifier name, RelationalPersistentEntity this.path = getPath(name.getReference()); this.property = this.path == null ? property : this.path.getLeafProperty(); - this.sqlType = this.property != null ? converter.getSqlType(this.property) : JdbcUtils.TYPE_UNKNOWN; + this.sqlType = this.property != null ? converter.getTargetSqlType(this.property) : JdbcUtil.TYPE_UNKNOWN; if (this.property != null) { this.embedded = this.property.isEmbedded(); @@ -839,7 +839,7 @@ public TypeInformation getTypeHint() { * @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#getSqlType() */ @Override - public int getSqlType() { + public SQLType getSqlType() { return this.sqlType; } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java index e6b81296b7..2a329fb2f1 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java @@ -18,7 +18,7 @@ import static org.springframework.data.jdbc.repository.query.JdbcQueryExecution.*; import java.lang.reflect.Constructor; -import java.sql.JDBCType; +import java.sql.SQLType; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.BeanFactory; @@ -161,9 +161,9 @@ private void convertAndAddParameter(MapSqlParameterSource parameters, Parameter Class conversionTargetType = JdbcColumnTypes.INSTANCE.resolvePrimitiveType(parameterType); JdbcValue jdbcValue = converter.writeJdbcValue(value, conversionTargetType, - JdbcUtil.sqlTypeFor(conversionTargetType)); + JdbcUtil.targetSqlTypeFor(conversionTargetType)); - JDBCType jdbcType = jdbcValue.getJdbcType(); + SQLType jdbcType = jdbcValue.getJdbcType(); if (jdbcType == null) { parameters.addValue(parameterName, jdbcValue.getValue()); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java index e5d0c291f4..29d0895876 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java @@ -19,6 +19,7 @@ import java.math.BigInteger; import java.sql.Date; import java.sql.JDBCType; +import java.sql.SQLType; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; @@ -38,32 +39,48 @@ */ public final class JdbcUtil { - private static final Map, Integer> sqlTypeMappings = new HashMap<>(); + public static final SQLType TYPE_UNKNOWN = new SQLType() { + @Override + public String getName() { + return "UNKNOWN"; + } + + @Override + public String getVendor() { + return "Spring"; + } + + @Override + public Integer getVendorTypeNumber() { + return JdbcUtils.TYPE_UNKNOWN; + } + } ; + private static final Map, SQLType> sqlTypeMappings = new HashMap<>(); static { - sqlTypeMappings.put(String.class, Types.VARCHAR); - sqlTypeMappings.put(BigInteger.class, Types.BIGINT); - sqlTypeMappings.put(BigDecimal.class, Types.DECIMAL); - sqlTypeMappings.put(Byte.class, Types.TINYINT); - sqlTypeMappings.put(byte.class, Types.TINYINT); - sqlTypeMappings.put(Short.class, Types.SMALLINT); - sqlTypeMappings.put(short.class, Types.SMALLINT); - sqlTypeMappings.put(Integer.class, Types.INTEGER); - sqlTypeMappings.put(int.class, Types.INTEGER); - sqlTypeMappings.put(Long.class, Types.BIGINT); - sqlTypeMappings.put(long.class, Types.BIGINT); - sqlTypeMappings.put(Double.class, Types.DOUBLE); - sqlTypeMappings.put(double.class, Types.DOUBLE); - sqlTypeMappings.put(Float.class, Types.REAL); - sqlTypeMappings.put(float.class, Types.REAL); - sqlTypeMappings.put(Boolean.class, Types.BIT); - sqlTypeMappings.put(boolean.class, Types.BIT); - sqlTypeMappings.put(byte[].class, Types.VARBINARY); - sqlTypeMappings.put(Date.class, Types.DATE); - sqlTypeMappings.put(Time.class, Types.TIME); - sqlTypeMappings.put(Timestamp.class, Types.TIMESTAMP); - sqlTypeMappings.put(OffsetDateTime.class, Types.TIMESTAMP_WITH_TIMEZONE); + sqlTypeMappings.put(String.class, JDBCType.VARCHAR); + sqlTypeMappings.put(BigInteger.class, JDBCType.BIGINT); + sqlTypeMappings.put(BigDecimal.class, JDBCType.DECIMAL); + sqlTypeMappings.put(Byte.class, JDBCType.TINYINT); + sqlTypeMappings.put(byte.class, JDBCType.TINYINT); + sqlTypeMappings.put(Short.class, JDBCType.SMALLINT); + sqlTypeMappings.put(short.class, JDBCType.SMALLINT); + sqlTypeMappings.put(Integer.class, JDBCType.INTEGER); + sqlTypeMappings.put(int.class, JDBCType.INTEGER); + sqlTypeMappings.put(Long.class, JDBCType.BIGINT); + sqlTypeMappings.put(long.class, JDBCType.BIGINT); + sqlTypeMappings.put(Double.class, JDBCType.DOUBLE); + sqlTypeMappings.put(double.class, JDBCType.DOUBLE); + sqlTypeMappings.put(Float.class, JDBCType.REAL); + sqlTypeMappings.put(float.class, JDBCType.REAL); + sqlTypeMappings.put(Boolean.class, JDBCType.BIT); + sqlTypeMappings.put(boolean.class, JDBCType.BIT); + sqlTypeMappings.put(byte[].class, JDBCType.VARBINARY); + sqlTypeMappings.put(Date.class, JDBCType.DATE); + sqlTypeMappings.put(Time.class, JDBCType.TIME); + sqlTypeMappings.put(Timestamp.class, JDBCType.TIMESTAMP); + sqlTypeMappings.put(OffsetDateTime.class, JDBCType.TIMESTAMP_WITH_TIMEZONE); } private JdbcUtil() { @@ -76,7 +93,9 @@ private JdbcUtil() { * * @param type The type of value to be bound to a {@link java.sql.PreparedStatement}. * @return One of the values defined in {@link Types} or {@link JdbcUtils#TYPE_UNKNOWN}. + * @deprecated use {@link #targetSqlTypeFor(Class)} instead. */ + @Deprecated public static int sqlTypeFor(Class type) { Assert.notNull(type, "Type must not be null."); @@ -85,16 +104,36 @@ public static int sqlTypeFor(Class type) { .filter(k -> k.isAssignableFrom(type)) // .findFirst() // .map(sqlTypeMappings::get) // + .map(SQLType::getVendorTypeNumber) .orElse(JdbcUtils.TYPE_UNKNOWN); } + /** + * Returns the {@link SQLType} value suitable for passing a value of the provided type to JDBC driver. + * + * @param type The type of value to be bound to a {@link java.sql.PreparedStatement}. + * @return a matching {@link SQLType} or {@link #TYPE_UNKNOWN}. + */ + public static SQLType targetSqlTypeFor(Class type) { + + Assert.notNull(type, "Type must not be null."); + + return sqlTypeMappings.keySet().stream() // + .filter(k -> k.isAssignableFrom(type)) // + .findFirst() // + .map(sqlTypeMappings::get) // + .orElse(JdbcUtil.TYPE_UNKNOWN); + } + /** * Converts a {@link JDBCType} to an {@code int} value as defined in {@link Types}. * * @param jdbcType value to be converted. May be {@literal null}. * @return One of the values defined in {@link Types} or {@link JdbcUtils#TYPE_UNKNOWN}. + * @deprecated there is no replacement. */ - public static int sqlTypeFor(@Nullable JDBCType jdbcType) { + @Deprecated + public static int sqlTypeFor(@Nullable SQLType jdbcType) { return jdbcType == null ? JdbcUtils.TYPE_UNKNOWN : jdbcType.getVendorTypeNumber(); } @@ -104,9 +143,11 @@ public static int sqlTypeFor(@Nullable JDBCType jdbcType) { * * @param sqlType One of the values defined in {@link Types} or {@link JdbcUtils#TYPE_UNKNOWN}. * @return a matching {@link JDBCType} instance or {@literal null}. + * @deprecated This is now a noop */ @Nullable - public static JDBCType jdbcTypeFor(int sqlType) { + @Deprecated + public static SQLType jdbcTypeFor(int sqlType) { if (sqlType == JdbcUtils.TYPE_UNKNOWN) { return null; @@ -121,9 +162,11 @@ public static JDBCType jdbcTypeFor(int sqlType) { * * @param type The type of value to be bound to a {@link java.sql.PreparedStatement}. * @return a matching {@link JDBCType} instance or {@literal null}. + * @deprecated Use {@link #targetSqlTypeFor(Class)} instead. */ - @Nullable - public static JDBCType jdbcTypeFor(Class type) { - return jdbcTypeFor(sqlTypeFor(type)); + @Deprecated + public static SQLType jdbcTypeFor(Class type) { + + return targetSqlTypeFor(type); } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverterUnitTests.java index e382206680..70b7763c92 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverterUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverterUnitTests.java @@ -136,7 +136,7 @@ void conversionOfDateLikeValueAndBackYieldsOriginalValue() { void conversionOfPrimitiveArrays() { int[] ints = { 1, 2, 3, 4, 5 }; - JdbcValue converted = converter.writeJdbcValue(ints, ints.getClass(), JdbcUtil.sqlTypeFor(ints.getClass())); + JdbcValue converted = converter.writeJdbcValue(ints, ints.getClass(), JdbcUtil.targetSqlTypeFor(ints.getClass())); assertThat(converted.getValue()).isInstanceOf(Array.class); assertThat(typeFactory.arraySource).containsExactly(1, 2, 3, 4, 5); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/support/JdbcUtilTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/support/JdbcUtilTests.java index 371c752289..eb52f0f12d 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/support/JdbcUtilTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/support/JdbcUtilTests.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.*; -import java.sql.Types; +import java.sql.JDBCType; import java.time.OffsetDateTime; import org.junit.jupiter.api.Test; @@ -31,6 +31,6 @@ class JdbcUtilTests { @Test void test() { - assertThat(JdbcUtil.sqlTypeFor(OffsetDateTime.class)).isEqualTo(Types.TIMESTAMP_WITH_TIMEZONE); + assertThat(JdbcUtil.targetSqlTypeFor(OffsetDateTime.class)).isEqualTo(JDBCType.TIMESTAMP_WITH_TIMEZONE); } } From 44b7b8fdf3130beebb736b54adc53d10d4c98723 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 4 Feb 2022 14:49:25 +0100 Subject: [PATCH 15/51] Polishing. Extract docker and artifactory credentials into property file. See #1151 --- Jenkinsfile | 22 +++++++++++----------- ci/pipeline.properties | 5 +++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 87abc16251..a20fac4340 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,13 +32,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials('hub.docker.com-springbuildmaster') - ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + DOCKER_HUB = credentials("${p['docker.credentials']}") + ARTIFACTORY = credentials("${p['artifactory.credentials']}") } steps { script { - docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,all-dbs ci/test.sh" @@ -65,13 +65,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials('hub.docker.com-springbuildmaster') - ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + DOCKER_HUB = credentials("${p['docker.credentials']}") + ARTIFACTORY = credentials("${p['artifactory.credentials']}") } steps { script { - docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,java11 ci/test.sh" @@ -89,13 +89,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials('hub.docker.com-springbuildmaster') - ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + DOCKER_HUB = credentials("${p['docker.credentials']}") + ARTIFACTORY = credentials("${p['artifactory.credentials']}") } steps { script { - docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,java11 ci/test.sh" @@ -122,12 +122,12 @@ pipeline { options { timeout(time: 20, unit: 'MINUTES') } environment { - ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + ARTIFACTORY = credentials("${p['artifactory.credentials']}") } steps { script { - docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) { sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-jdbc-non-root ' + '-Dartifactory.server=https://repo.spring.io ' + diff --git a/ci/pipeline.properties b/ci/pipeline.properties index 5d91102d25..9d382ca66b 100644 --- a/ci/pipeline.properties +++ b/ci/pipeline.properties @@ -22,3 +22,8 @@ docker.cassandra.3.version=3.11.10 # Docker environment settings docker.java.inside.basic=-v $HOME:/tmp/jenkins-home docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home + +# Credentials +docker.registry= +docker.credentials=hub.docker.com-springbuildmaster +artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c From f48bbabc285f39a5e218032a80a09341b135c6af Mon Sep 17 00:00:00 2001 From: Chirag Tailor Date: Thu, 3 Feb 2022 10:28:47 -0600 Subject: [PATCH 16/51] Null precedence is now supported if the underlying database supports it. Original pull request #1156 Closes #821 --- .../data/jdbc/core/convert/SqlGenerator.java | 5 +- ...JdbcAggregateTemplateIntegrationTests.java | 15 ++++ .../core/convert/SqlGeneratorUnitTests.java | 24 ++++++- .../jdbc/testing/TestDatabaseFeatures.java | 8 ++- .../core/dialect/AbstractDialect.java | 15 +++- .../data/relational/core/dialect/Dialect.java | 12 +++- .../relational/core/dialect/MySqlDialect.java | 5 ++ .../core/dialect/OrderByNullHandling.java | 71 +++++++++++++++++++ .../core/dialect/SqlServerDialect.java | 5 ++ .../core/sql/render/OrderByClauseVisitor.java | 13 ++-- .../core/sql/render/SelectRenderContext.java | 17 ++++- .../PostgresDialectRenderingUnitTests.java | 64 ++++++++++++++++- .../SqlServerDialectRenderingUnitTests.java | 21 +++++- 13 files changed, 258 insertions(+), 17 deletions(-) create mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index 80fa379a49..a95c9b1933 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +51,7 @@ * @author Milan Milanov * @author Myeonghyeon Lee * @author Mikhail Polivakha + * @author Chirag Tailor */ class SqlGenerator { @@ -714,7 +715,7 @@ private OrderByField orderToOrderByField(Sort.Order order) { SqlIdentifier columnName = this.entity.getRequiredPersistentProperty(order.getProperty()).getColumnName(); Column column = Column.create(columnName, this.getTable()); - return OrderByField.from(column, order.getDirection()); + return OrderByField.from(column, order.getDirection()).withNullHandling(order.getNullHandling()); } /** diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 4153ac6b3b..fa79aec3bd 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -257,6 +257,21 @@ void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() { .containsExactly("Star"); } + @Test // GH-821 + @EnabledOnFeature({SUPPORTS_QUOTED_IDS, SUPPORTS_NULL_HANDLING}) + void saveAndLoadManyEntitiesWithReferencedEntitySortedWithNullHandling() { + + template.save(createLegoSet(null)); + template.save(createLegoSet("Star")); + template.save(createLegoSet("Frozen")); + + Iterable reloadedLegoSets = template.findAll(LegoSet.class, Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); + + assertThat(reloadedLegoSets) // + .extracting("name") // + .containsExactly("Frozen", "Star", null); + } + @Test // DATAJDBC-112 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) void saveAndLoadManyEntitiesByIdWithReferencedEntity() { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index 363d9c9d1d..7ea24dfebe 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import org.springframework.data.annotation.Id; import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Version; @@ -64,6 +63,7 @@ * @author Milan Milanov * @author Myeonghyeon Lee * @author Mikhail Polivakha + * @author Chirag Tailor */ class SqlGeneratorUnitTests { @@ -245,6 +245,26 @@ void findAllSortedByMultipleFields() { "x_other ASC"); } + @Test // GH-821 + void findAllSortedWithNullHandling_resolvesNullHandlingWhenDialectSupportsIt() { + + SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, PostgresDialect.INSTANCE); + + String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); + + assertThat(sql).contains("ORDER BY \"dummy_entity\".\"x_name\" ASC NULLS LAST"); + } + + @Test // GH-821 + void findAllSortedWithNullHandling_ignoresNullHandlingWhenDialectDoesNotSupportIt() { + + SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, SqlServerDialect.INSTANCE); + + String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); + + assertThat(sql).endsWith("ORDER BY dummy_entity.x_name ASC"); + } + @Test // DATAJDBC-101 void findAllPagedByUnpaged() { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java index 6e3e65a484..d252745034 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ * presence or absence of features in tests. * * @author Jens Schauder + * @author Chirag Tailor */ public class TestDatabaseFeatures { @@ -83,6 +84,10 @@ private void supportsMultiDimensionalArrays() { assumeThat(database).isNotIn(Database.H2, Database.Hsql); } + private void supportsNullHandling() { + assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer); + } + public void databaseIs(Database database) { assumeThat(this.database).isEqualTo(database); } @@ -115,6 +120,7 @@ public enum Feature { SUPPORTS_ARRAYS(TestDatabaseFeatures::supportsArrays), // SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES(TestDatabaseFeatures::supportsGeneratedIdsInReferencedEntities), // SUPPORTS_NANOSECOND_PRECISION(TestDatabaseFeatures::supportsNanosecondPrecision), // + SUPPORTS_NULL_HANDLING(TestDatabaseFeatures::supportsNullHandling), IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), // IS_HSQL(f -> f.databaseIs(Database.Hsql)); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java index 6563df66a3..7043a9f734 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.OptionalLong; import java.util.function.Function; +import org.springframework.data.domain.Sort; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.LockOptions; import org.springframework.data.relational.core.sql.Select; @@ -28,6 +29,7 @@ * * @author Mark Paluch * @author Myeonghyeon Lee + * @author Chirag Tailor * @since 1.1 */ public abstract class AbstractDialect implements Dialect { @@ -42,7 +44,7 @@ public SelectRenderContext getSelectContext() { Function afterFromTable = getAfterFromTable(); Function afterOrderBy = getAfterOrderBy(); - return new DialectSelectRenderContext(afterFromTable, afterOrderBy); + return new DialectSelectRenderContext(afterFromTable, afterOrderBy, orderByNullHandling()); } /** @@ -105,12 +107,14 @@ static class DialectSelectRenderContext implements SelectRenderContext { private final Function afterFromTable; private final Function afterOrderBy; + private final OrderByNullHandling orderByNullHandling; DialectSelectRenderContext(Function afterFromTable, - Function afterOrderBy) { + Function afterOrderBy, OrderByNullHandling orderByNullHandling) { this.afterFromTable = afterFromTable; this.afterOrderBy = afterOrderBy; + this.orderByNullHandling = orderByNullHandling; } /* @@ -130,6 +134,11 @@ static class DialectSelectRenderContext implements SelectRenderContext { public Function afterOrderBy(boolean hasOrderBy) { return afterOrderBy; } + + @Override + public String evaluateOrderByNullHandling(Sort.NullHandling nullHandling) { + return orderByNullHandling.evaluate(nullHandling); + } } /** diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java index 5febb8c52f..eee10f0b6c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ * @author Myeonghyeon Lee * @author Christoph Strobl * @author Mikhail Polivakha + * @author Chirag Tailor * @since 1.1 */ public interface Dialect { @@ -120,4 +121,13 @@ default Set> simpleTypes() { default InsertRenderContext getInsertRenderContext() { return InsertRenderContexts.DEFAULT; } + + /** + * Return the {@link OrderByNullHandling} used by this dialect. + * + * @return the {@link OrderByNullHandling} used by this dialect. + */ + default OrderByNullHandling orderByNullHandling() { + return OrderByNullHandling.SQL_STANDARD; + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java index 6032582186..a1a9919293 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java @@ -169,4 +169,9 @@ public IdentifierProcessing getIdentifierProcessing() { public Collection getConverters() { return Collections.singletonList(TimestampAtUtcToOffsetDateTimeConverter.INSTANCE); } + + @Override + public OrderByNullHandling orderByNullHandling() { + return OrderByNullHandling.NONE; + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java new file mode 100644 index 0000000000..4dcadc8eff --- /dev/null +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java @@ -0,0 +1,71 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.relational.core.dialect; + +import org.springframework.data.domain.Sort; + +/** + * Represents how the {@link Sort.NullHandling} option of an {@code ORDER BY} sort expression is to be evaluated. + * + * @author Chirag Tailor + */ +public interface OrderByNullHandling { + /** + * An {@link OrderByNullHandling} that can be used for databases conforming to the SQL standard which uses + * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to make null values appear before + * or after non-null values in the result set. + */ + OrderByNullHandling SQL_STANDARD = new SqlStandardOrderByNullHandling(); + + /** + * An {@link OrderByNullHandling} that can be used for databases that do not support the SQL standard usage of + * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to control where null values appear + * respective to non-null values in the result set. + */ + OrderByNullHandling NONE = nullHandling -> ""; + + /** + * Converts a {@link Sort.NullHandling} option to the appropriate SQL text to be included an {@code ORDER BY} sort + * expression. + */ + String evaluate(Sort.NullHandling nullHandling); + + /** + * An {@link OrderByNullHandling} implementation for databases conforming to the SQL standard which uses + * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to make null values appear before + * or after non-null values in the result set. + * + * @author Chirag Tailor + */ + class SqlStandardOrderByNullHandling implements OrderByNullHandling { + + private static final String NULLS_FIRST = "NULLS FIRST"; + private static final String NULLS_LAST = "NULLS LAST"; + private static final String UNSPECIFIED = ""; + + @Override + public String evaluate(Sort.NullHandling nullHandling) { + + switch (nullHandling) { + case NULLS_FIRST: return NULLS_FIRST; + case NULLS_LAST: return NULLS_LAST; + case NATIVE: return UNSPECIFIED; + default: + throw new UnsupportedOperationException("Sort.NullHandling " + nullHandling + " not supported"); + } + } + } +} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java index 11ae0d3cf3..7f393e05e1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java @@ -156,4 +156,9 @@ public IdentifierProcessing getIdentifierProcessing() { public InsertRenderContext getInsertRenderContext() { return InsertRenderContexts.MS_SQL_SERVER; } + + @Override + public OrderByNullHandling orderByNullHandling() { + return OrderByNullHandling.NONE; + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java index a918231dd2..949a234a60 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ * * @author Mark Paluch * @author Jens Schauder + * @author Chirag Tailor * @since 1.1 */ class OrderByClauseVisitor extends TypedSubtreeVisitor implements PartRenderer { @@ -59,11 +60,15 @@ Delegation enterMatched(OrderByField segment) { @Override Delegation leaveMatched(OrderByField segment) { - OrderByField field = segment; + if (segment.getDirection() != null) { + builder.append(" ") // + .append(segment.getDirection()); + } - if (field.getDirection() != null) { + String nullHandling = context.getSelectRenderContext().evaluateOrderByNullHandling(segment.getNullHandling()); + if (!nullHandling.isEmpty()) { builder.append(" ") // - .append(field.getDirection()); + .append(nullHandling); } return Delegation.leave(); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java index 74592f3915..12bbaa0d5e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,20 @@ import java.util.OptionalLong; import java.util.function.Function; +import org.springframework.data.domain.Sort; +import org.springframework.data.relational.core.dialect.OrderByNullHandling; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.Select; /** * Render context specifically for {@code SELECT} statements. This interface declares rendering hooks that are called - * before/after a specific {@code SELECT} clause part. The rendering content is appended directly after/before an + * before/after/during a specific {@code SELECT} clause part. The rendering content is appended directly after/before an * element without further whitespace processing. Hooks are responsible for adding required surrounding whitespaces. * * @author Mark Paluch * @author Myeonghyeon Lee * @author Jens Schauder + * @author Chirag Tailor * @since 1.1 */ public interface SelectRenderContext { @@ -86,4 +89,14 @@ public interface SelectRenderContext { return lockPrefix; }; } + + /** + * Customization hook: Rendition of the null handling option for an {@code ORDER BY} sort expression. + * + * @param nullHandling the {@link Sort.NullHandling} for the {@code ORDER BY} sort expression. Must not be {@literal null}. + * @return render {@link String} SQL text to be included in an {@code ORDER BY} sort expression. + */ + default String evaluateOrderByNullHandling(Sort.NullHandling nullHandling) { + return OrderByNullHandling.NONE.evaluate(nullHandling); + } } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java index c2aca005e3..ddf09cdcfc 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Sort; +import org.springframework.data.relational.core.sql.Column; import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.core.sql.OrderByField; import org.springframework.data.relational.core.sql.Select; import org.springframework.data.relational.core.sql.StatementBuilder; import org.springframework.data.relational.core.sql.Table; @@ -33,6 +36,7 @@ * @author Mark Paluch * @author Jens Schauder * @author Myeonghyeon Lee + * @author Chirag Tailor */ public class PostgresDialectRenderingUnitTests { @@ -147,4 +151,62 @@ public void shouldRenderSelectWithLimitWithLockRead() { assertThat(sql).isEqualTo("SELECT foo.* FROM foo LIMIT 10 FOR SHARE OF foo"); } + + @Test // GH-821 + void shouldRenderSelectOrderByWithNoOptions() { + + Table table = Table.create("foo"); + Select select = StatementBuilder.select(table.asterisk()) + .from(table) + .orderBy(OrderByField.from(Column.create("bar", table))) + .build(); + + String sql = SqlRenderer.create(factory.createRenderContext()).render(select); + + assertThat(sql).isEqualTo("SELECT foo.* FROM foo ORDER BY foo.bar"); + } + + @Test // GH-821 + void shouldRenderSelectOrderByWithDirection() { + + Table table = Table.create("foo"); + Select select = StatementBuilder.select(table.asterisk()) + .from(table) + .orderBy(OrderByField.from(Column.create("bar", table), Sort.Direction.ASC)) + .build(); + + String sql = SqlRenderer.create(factory.createRenderContext()).render(select); + + assertThat(sql).isEqualTo("SELECT foo.* FROM foo ORDER BY foo.bar ASC"); + } + + @Test // GH-821 + void shouldRenderSelectOrderByWithNullHandling() { + + Table table = Table.create("foo"); + Select select = StatementBuilder.select(table.asterisk()) + .from(table) + .orderBy(OrderByField.from(Column.create("bar", table)) + .withNullHandling(Sort.NullHandling.NULLS_FIRST)) + .build(); + + String sql = SqlRenderer.create(factory.createRenderContext()).render(select); + + assertThat(sql).isEqualTo("SELECT foo.* FROM foo ORDER BY foo.bar NULLS FIRST"); + } + + @Test // GH-821 + void shouldRenderSelectOrderByWithDirectionAndNullHandling() { + + Table table = Table.create("foo"); + Select select = StatementBuilder.select(table.asterisk()) + .from(table) + .orderBy(OrderByField.from(Column.create("bar", table), Sort.Direction.DESC) + .withNullHandling(Sort.NullHandling.NULLS_FIRST)) + .build(); + + String sql = SqlRenderer.create(factory.createRenderContext()).render(select); + + assertThat(sql).isEqualTo("SELECT foo.* FROM foo ORDER BY foo.bar DESC NULLS FIRST"); + } } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectRenderingUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectRenderingUnitTests.java index 2c2f865c09..403faa241f 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectRenderingUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectRenderingUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Sort; +import org.springframework.data.relational.core.sql.Column; import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.core.sql.OrderByField; import org.springframework.data.relational.core.sql.Select; import org.springframework.data.relational.core.sql.StatementBuilder; import org.springframework.data.relational.core.sql.Table; @@ -33,6 +36,7 @@ * @author Mark Paluch * @author Jens Schauder * @author Myeonghyeon Lee + * @author Chirag Tailor */ public class SqlServerDialectRenderingUnitTests { @@ -192,4 +196,19 @@ public void shouldRenderSelectWithLimitOffsetAndOrderByWithLockRead() { assertThat(sql).isEqualTo("SELECT foo.* FROM foo WITH (HOLDLOCK, ROWLOCK) ORDER BY foo.column_1 OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY"); } + + @Test // GH-821 + void shouldRenderSelectOrderByIgnoringNullHandling() { + + Table table = Table.create("foo"); + Select select = StatementBuilder.select(table.asterisk()) + .from(table) + .orderBy(OrderByField.from(Column.create("bar", table)) + .withNullHandling(Sort.NullHandling.NULLS_FIRST)) + .build(); + + String sql = SqlRenderer.create(factory.createRenderContext()).render(select); + + assertThat(sql).isEqualTo("SELECT foo.* FROM foo ORDER BY foo.bar"); + } } From 49898726a44bb43c278b55c3297ce442fba016d1 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 8 Feb 2022 12:04:51 +0100 Subject: [PATCH 17/51] Polishing. Rename "null handling" to "null precedence". This is somewhat inconsistent with commons null handling, but more descriptive. Minor formatting. Original pull request #1156 See #821 --- .../JdbcAggregateTemplateIntegrationTests.java | 4 ++-- .../data/jdbc/testing/TestDatabaseFeatures.java | 4 ++-- .../relational/core/dialect/AbstractDialect.java | 8 ++++---- .../data/relational/core/dialect/Dialect.java | 9 +++++---- .../relational/core/dialect/MySqlDialect.java | 4 ++-- ...llHandling.java => OrderByNullPrecedence.java} | 15 ++++++++------- .../relational/core/dialect/SqlServerDialect.java | 4 ++-- .../core/sql/render/OrderByClauseVisitor.java | 8 +++++--- .../core/sql/render/SelectRenderContext.java | 5 +++-- .../PostgresDialectRenderingUnitTests.java | 2 +- 10 files changed, 34 insertions(+), 29 deletions(-) rename spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/{OrderByNullHandling.java => OrderByNullPrecedence.java} (80%) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index fa79aec3bd..5a8b1fd77c 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -258,8 +258,8 @@ void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() { } @Test // GH-821 - @EnabledOnFeature({SUPPORTS_QUOTED_IDS, SUPPORTS_NULL_HANDLING}) - void saveAndLoadManyEntitiesWithReferencedEntitySortedWithNullHandling() { + @EnabledOnFeature({SUPPORTS_QUOTED_IDS, SUPPORTS_NULL_PRECEDENCE}) + void saveAndLoadManyEntitiesWithReferencedEntitySortedWithNullPrecedence() { template.save(createLegoSet(null)); template.save(createLegoSet("Star")); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java index d252745034..430fc9f16d 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java @@ -84,7 +84,7 @@ private void supportsMultiDimensionalArrays() { assumeThat(database).isNotIn(Database.H2, Database.Hsql); } - private void supportsNullHandling() { + private void supportsNullPrecedence() { assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer); } @@ -120,7 +120,7 @@ public enum Feature { SUPPORTS_ARRAYS(TestDatabaseFeatures::supportsArrays), // SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES(TestDatabaseFeatures::supportsGeneratedIdsInReferencedEntities), // SUPPORTS_NANOSECOND_PRECISION(TestDatabaseFeatures::supportsNanosecondPrecision), // - SUPPORTS_NULL_HANDLING(TestDatabaseFeatures::supportsNullHandling), + SUPPORTS_NULL_PRECEDENCE(TestDatabaseFeatures::supportsNullPrecedence), IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), // IS_HSQL(f -> f.databaseIs(Database.Hsql)); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java index 7043a9f734..488e6f3553 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AbstractDialect.java @@ -107,14 +107,14 @@ static class DialectSelectRenderContext implements SelectRenderContext { private final Function afterFromTable; private final Function afterOrderBy; - private final OrderByNullHandling orderByNullHandling; + private final OrderByNullPrecedence orderByNullPrecedence; DialectSelectRenderContext(Function afterFromTable, - Function afterOrderBy, OrderByNullHandling orderByNullHandling) { + Function afterOrderBy, OrderByNullPrecedence orderByNullPrecedence) { this.afterFromTable = afterFromTable; this.afterOrderBy = afterOrderBy; - this.orderByNullHandling = orderByNullHandling; + this.orderByNullPrecedence = orderByNullPrecedence; } /* @@ -137,7 +137,7 @@ static class DialectSelectRenderContext implements SelectRenderContext { @Override public String evaluateOrderByNullHandling(Sort.NullHandling nullHandling) { - return orderByNullHandling.evaluate(nullHandling); + return orderByNullPrecedence.evaluate(nullHandling); } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java index eee10f0b6c..1b47eb7c73 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java @@ -123,11 +123,12 @@ default InsertRenderContext getInsertRenderContext() { } /** - * Return the {@link OrderByNullHandling} used by this dialect. + * Return the {@link OrderByNullPrecedence} used by this dialect. * - * @return the {@link OrderByNullHandling} used by this dialect. + * @return the {@link OrderByNullPrecedence} used by this dialect. + * @since 2.4 */ - default OrderByNullHandling orderByNullHandling() { - return OrderByNullHandling.SQL_STANDARD; + default OrderByNullPrecedence orderByNullHandling() { + return OrderByNullPrecedence.SQL_STANDARD; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java index a1a9919293..ce05a21fe3 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java @@ -171,7 +171,7 @@ public Collection getConverters() { } @Override - public OrderByNullHandling orderByNullHandling() { - return OrderByNullHandling.NONE; + public OrderByNullPrecedence orderByNullHandling() { + return OrderByNullPrecedence.NONE; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java similarity index 80% rename from spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java rename to spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java index 4dcadc8eff..3bc8d56ae1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullHandling.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java @@ -21,21 +21,22 @@ * Represents how the {@link Sort.NullHandling} option of an {@code ORDER BY} sort expression is to be evaluated. * * @author Chirag Tailor + * @since 2.4 */ -public interface OrderByNullHandling { +public interface OrderByNullPrecedence { /** - * An {@link OrderByNullHandling} that can be used for databases conforming to the SQL standard which uses + * An {@link OrderByNullPrecedence} that can be used for databases conforming to the SQL standard which uses * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to make null values appear before * or after non-null values in the result set. */ - OrderByNullHandling SQL_STANDARD = new SqlStandardOrderByNullHandling(); + OrderByNullPrecedence SQL_STANDARD = new SqlStandardOrderByNullPrecedence(); /** - * An {@link OrderByNullHandling} that can be used for databases that do not support the SQL standard usage of + * An {@link OrderByNullPrecedence} that can be used for databases that do not support the SQL standard usage of * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to control where null values appear * respective to non-null values in the result set. */ - OrderByNullHandling NONE = nullHandling -> ""; + OrderByNullPrecedence NONE = nullHandling -> ""; /** * Converts a {@link Sort.NullHandling} option to the appropriate SQL text to be included an {@code ORDER BY} sort @@ -44,13 +45,13 @@ public interface OrderByNullHandling { String evaluate(Sort.NullHandling nullHandling); /** - * An {@link OrderByNullHandling} implementation for databases conforming to the SQL standard which uses + * An {@link OrderByNullPrecedence} implementation for databases conforming to the SQL standard which uses * {@code NULLS FIRST} and {@code NULLS LAST} in {@code ORDER BY} sort expressions to make null values appear before * or after non-null values in the result set. * * @author Chirag Tailor */ - class SqlStandardOrderByNullHandling implements OrderByNullHandling { + class SqlStandardOrderByNullPrecedence implements OrderByNullPrecedence { private static final String NULLS_FIRST = "NULLS FIRST"; private static final String NULLS_LAST = "NULLS LAST"; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java index 7f393e05e1..b25335abd6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java @@ -158,7 +158,7 @@ public InsertRenderContext getInsertRenderContext() { } @Override - public OrderByNullHandling orderByNullHandling() { - return OrderByNullHandling.NONE; + public OrderByNullPrecedence orderByNullHandling() { + return OrderByNullPrecedence.NONE; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java index 949a234a60..5cdf0ede02 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitor.java @@ -61,14 +61,16 @@ Delegation enterMatched(OrderByField segment) { Delegation leaveMatched(OrderByField segment) { if (segment.getDirection() != null) { + builder.append(" ") // .append(segment.getDirection()); } - String nullHandling = context.getSelectRenderContext().evaluateOrderByNullHandling(segment.getNullHandling()); - if (!nullHandling.isEmpty()) { + String nullPrecedence = context.getSelectRenderContext().evaluateOrderByNullHandling(segment.getNullHandling()); + if (!nullPrecedence.isEmpty()) { + builder.append(" ") // - .append(nullHandling); + .append(nullPrecedence); } return Delegation.leave(); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java index 12bbaa0d5e..adfa14f285 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectRenderContext.java @@ -19,7 +19,7 @@ import java.util.function.Function; import org.springframework.data.domain.Sort; -import org.springframework.data.relational.core.dialect.OrderByNullHandling; +import org.springframework.data.relational.core.dialect.OrderByNullPrecedence; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.Select; @@ -95,8 +95,9 @@ public interface SelectRenderContext { * * @param nullHandling the {@link Sort.NullHandling} for the {@code ORDER BY} sort expression. Must not be {@literal null}. * @return render {@link String} SQL text to be included in an {@code ORDER BY} sort expression. + * @since 2.4 */ default String evaluateOrderByNullHandling(Sort.NullHandling nullHandling) { - return OrderByNullHandling.NONE.evaluate(nullHandling); + return OrderByNullPrecedence.NONE.evaluate(nullHandling); } } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java index ddf09cdcfc..27b318340b 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectRenderingUnitTests.java @@ -181,7 +181,7 @@ void shouldRenderSelectOrderByWithDirection() { } @Test // GH-821 - void shouldRenderSelectOrderByWithNullHandling() { + void shouldRenderSelectOrderByWithNullPrecedence() { Table table = Table.create("foo"); Select select = StatementBuilder.select(table.asterisk()) From dbf5dd56a6ddde77e1df5aa3733e36c2a6bbb487 Mon Sep 17 00:00:00 2001 From: Jan Michal Date: Tue, 8 Feb 2022 17:01:09 +0100 Subject: [PATCH 18/51] Fix a typo in the docs for query methods. Original pull request #1163 --- src/main/asciidoc/jdbc.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/asciidoc/jdbc.adoc b/src/main/asciidoc/jdbc.adoc index d4b9faa666..83b53ac4c3 100644 --- a/src/main/asciidoc/jdbc.adoc +++ b/src/main/asciidoc/jdbc.adoc @@ -550,11 +550,11 @@ The following table shows the keywords that are supported for query methods: | `Containing` on String | `findByFirstnameContaining(String name)` -| `firstname LIKE '%' name +'%'` +| `firstname LIKE '%' + name + '%'` | `NotContaining` on String | `findByFirstnameNotContaining(String name)` -| `firstname NOT LIKE '%' name +'%'` +| `firstname NOT LIKE '%' + name + '%'` | `(No keyword)` | `findByFirstname(String name)` From e68c3557c03f9cfefca07c539e7ecdd5076ac117 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Fri, 4 Feb 2022 16:22:40 +0100 Subject: [PATCH 19/51] Introduced pessimistic locks for derived queries. Methods which use the derive query functionality now can be annotated with `@Lock` to used a given `LockMode`. Right now there are two different modes `PESSIMISTIC_READ` and `PESSIMISTIC_WRITE`. Based on the dialect the right select is generated. For example for HSQLDB `Select ... FOR UPDATE`. See #1041 Original pull request #1158 --- .../query/JdbcCountQueryCreator.java | 9 ++- .../repository/query/JdbcQueryCreator.java | 15 ++++- .../repository/query/JdbcQueryMethod.java | 20 +++++- .../data/jdbc/repository/query/Lock.java | 39 ++++++++++++ .../repository/query/PartTreeJdbcQuery.java | 9 +-- .../JdbcRepositoryIntegrationTests.java | 16 ++++- .../query/JdbcQueryMethodUnitTests.java | 35 ++++++++++- .../query/PartTreeJdbcQueryUnitTests.java | 62 ++++++++++++++++--- 8 files changed, 184 insertions(+), 21 deletions(-) create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java index da89bc75aa..58c9158839 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,18 +30,21 @@ import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.parser.PartTree; +import java.util.Optional; + /** * {@link JdbcQueryCreator} that creates {@code COUNT(*)} queries without applying limit/offset and {@link Sort}. * * @author Mark Paluch + * @author Diego Krupitza * @since 2.2 */ class JdbcCountQueryCreator extends JdbcQueryCreator { JdbcCountQueryCreator(RelationalMappingContext context, PartTree tree, JdbcConverter converter, Dialect dialect, RelationalEntityMetadata entityMetadata, RelationalParameterAccessor accessor, boolean isSliceQuery, - ReturnedType returnedType) { - super(context, tree, converter, dialect, entityMetadata, accessor, isSliceQuery, returnedType); + ReturnedType returnedType, Optional lockMode) { + super(context, tree, converter, dialect, entityMetadata, accessor, isSliceQuery, returnedType, lockMode); } @Override diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java index d86549f141..e21248ca5d 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -57,6 +58,7 @@ * @author Mark Paluch * @author Jens Schauder * @author Myeonghyeon Lee + * @author Diego Krupitza * @since 2.0 */ class JdbcQueryCreator extends RelationalQueryCreator { @@ -69,6 +71,7 @@ class JdbcQueryCreator extends RelationalQueryCreator { private final RenderContextFactory renderContextFactory; private final boolean isSliceQuery; private final ReturnedType returnedType; + private final Optional lockMode; /** * Creates new instance of this class with the given {@link PartTree}, {@link JdbcConverter}, {@link Dialect}, @@ -85,7 +88,7 @@ class JdbcQueryCreator extends RelationalQueryCreator { */ JdbcQueryCreator(RelationalMappingContext context, PartTree tree, JdbcConverter converter, Dialect dialect, RelationalEntityMetadata entityMetadata, RelationalParameterAccessor accessor, boolean isSliceQuery, - ReturnedType returnedType) { + ReturnedType returnedType, Optional lockMode) { super(tree, accessor); Assert.notNull(converter, "JdbcConverter must not be null"); @@ -102,6 +105,7 @@ class JdbcQueryCreator extends RelationalQueryCreator { this.renderContextFactory = new RenderContextFactory(dialect); this.isSliceQuery = isSliceQuery; this.returnedType = returnedType; + this.lockMode = lockMode; } /** @@ -168,7 +172,12 @@ protected ParametrizedQuery complete(@Nullable Criteria criteria, Sort sort) { whereBuilder); selectOrderBuilder = applyOrderBy(sort, entity, table, selectOrderBuilder); - Select select = selectOrderBuilder.build(); + SelectBuilder.BuildSelect completedBuildSelect = selectOrderBuilder; + if (this.lockMode.isPresent()) { + completedBuildSelect = selectOrderBuilder.lock(this.lockMode.get().value()); + } + + Select select = completedBuildSelect.build(); String sql = SqlRenderer.create(renderContextFactory.createRenderContext()).render(select); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java index 4893418f29..9c979bcce9 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ * @author Kazuki Shimizu * @author Moises Cisneros * @author Hebert Coelho + * @author Diego Krupitza */ public class JdbcQueryMethod extends QueryMethod { @@ -168,7 +169,6 @@ public String getNamedQueryName() { return StringUtils.hasText(annotatedName) ? annotatedName : super.getNamedQueryName(); } - /** * Returns the class to be used as {@link org.springframework.jdbc.core.RowMapper} * @@ -245,6 +245,22 @@ Optional lookupQueryAnnotation() { return doFindAnnotation(Query.class); } + /** + * @return is a {@link Lock} annotation present or not. + */ + public boolean hasLockMode() { + return lookupLockAnnotation().isPresent(); + } + + /** + * Looks up the {@link Lock} annotation from the query method. + * + * @return the {@link Optional} wrapped {@link Lock} annotation. + */ + Optional lookupLockAnnotation() { + return doFindAnnotation(Lock.class); + } + @SuppressWarnings("unchecked") private Optional doFindAnnotation(Class annotationType) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java new file mode 100644 index 0000000000..0ef95ca0fb --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository.query; + +import org.springframework.data.annotation.QueryAnnotation; +import org.springframework.data.relational.core.sql.LockMode; + +import java.lang.annotation.*; + +/** + * Annotation to provide a lock mode for a given query. + * + * @author Diego Krupitza + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@QueryAnnotation +@Documented +public @interface Lock { + + /** + * Defines which type of {@link LockMode} we want to use. + */ + LockMode value() default LockMode.PESSIMISTIC_READ; + +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java index fccbe0a00c..94eff0ae58 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ * * @author Mark Paluch * @author Jens Schauder + * @author Diego Krupitza * @since 2.0 */ public class PartTreeJdbcQuery extends AbstractJdbcQuery { @@ -163,7 +164,7 @@ private JdbcQueryExecution getQueryExecution(ResultProcessor processor, RelationalEntityMetadata entityMetadata = getQueryMethod().getEntityInformation(); JdbcCountQueryCreator queryCreator = new JdbcCountQueryCreator(context, tree, converter, dialect, - entityMetadata, accessor, false, processor.getReturnedType()); + entityMetadata, accessor, false, processor.getReturnedType(), getQueryMethod().lookupLockAnnotation()); ParametrizedQuery countQuery = queryCreator.createQuery(Sort.unsorted()); Object count = singleObjectQuery((rs, i) -> rs.getLong(1)).execute(countQuery.getQuery(), @@ -181,7 +182,7 @@ protected ParametrizedQuery createQuery(RelationalParametersParameterAccessor ac RelationalEntityMetadata entityMetadata = getQueryMethod().getEntityInformation(); JdbcQueryCreator queryCreator = new JdbcQueryCreator(context, tree, converter, dialect, entityMetadata, accessor, - getQueryMethod().isSliceQuery(), returnedType); + getQueryMethod().isSliceQuery(), returnedType, this.getQueryMethod().lookupLockAnnotation()); return queryCreator.createQuery(getDynamicSort(accessor)); } @@ -231,7 +232,7 @@ static class PageQueryExecution implements JdbcQueryExecution> { private final LongSupplier countSupplier; PageQueryExecution(JdbcQueryExecution> delegate, Pageable pageable, - LongSupplier countSupplier) { + LongSupplier countSupplier) { this.delegate = delegate; this.pageable = pageable; this.countSupplier = countSupplier; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 66201877e3..70391a68a2 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +51,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jdbc.core.mapping.AggregateReference; +import org.springframework.data.jdbc.repository.query.Lock; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; @@ -61,6 +62,7 @@ import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent; import org.springframework.data.relational.core.mapping.event.AfterConvertEvent; import org.springframework.data.relational.core.mapping.event.AfterLoadEvent; +import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; @@ -331,6 +333,13 @@ public void findAllByQueryName() { assertThat(repository.findAllByNamedQuery()).hasSize(1); } + @Test + void findAllByFirstnameWithLock() { + DummyEntity dummyEntity = createDummyEntity(); + repository.save(dummyEntity); + assertThat(repository.findAllByName(dummyEntity.getName())).hasSize(1); + } + @Test // GH-1022 public void findAllByCustomQueryName() { @@ -574,7 +583,11 @@ private Instant createDummyBeforeAndAfterNow() { interface DummyEntityRepository extends CrudRepository { + @Lock(LockMode.PESSIMISTIC_WRITE) + List findAllByName(String name); + List findAllByNamedQuery(); + @Query(name = "DummyEntity.customQuery") List findAllByCustomNamedQuery(); @@ -624,6 +637,7 @@ interface DummyEntityRepository extends CrudRepository { List findByFlagTrue(); List findByRef(int ref); + List findByRef(AggregateReference ref); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java index 9089ba5fcb..d30a3cdb24 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; @@ -41,6 +42,7 @@ * @author Oliver Gierke * @author Moises Cisneros * @author Mark Paluch + * @author Diego Krupitza */ public class JdbcQueryMethodUnitTests { @@ -120,6 +122,37 @@ public void returnsNullIfNoQueryIsFound() throws NoSuchMethodException { assertThat(queryMethod.getDeclaredQuery()).isEqualTo(null); } + @Test // GH-1041 + void returnsQueryMethodWithLock() throws NoSuchMethodException { + + JdbcQueryMethod queryMethodWithWriteLock = createJdbcQueryMethod("queryMethodWithWriteLock"); + JdbcQueryMethod queryMethodWithReadLock = createJdbcQueryMethod("queryMethodWithReadLock"); + + assertThat(queryMethodWithWriteLock.hasLockMode()).isTrue(); + assertThat(queryMethodWithReadLock.hasLockMode()).isTrue(); + } + + @Test // GH-1041 + void returnsQueryMethodWithCorrectLockType() throws NoSuchMethodException { + + JdbcQueryMethod queryMethodWithWriteLock = createJdbcQueryMethod("queryMethodWithWriteLock"); + JdbcQueryMethod queryMethodWithReadLock = createJdbcQueryMethod("queryMethodWithReadLock"); + + assertThat(queryMethodWithWriteLock.lookupLockAnnotation()).isPresent(); + assertThat(queryMethodWithReadLock.lookupLockAnnotation()).isPresent(); + + assertThat(queryMethodWithWriteLock.lookupLockAnnotation().get().value()).isEqualTo(LockMode.PESSIMISTIC_WRITE); + assertThat(queryMethodWithReadLock.lookupLockAnnotation().get().value()).isEqualTo(LockMode.PESSIMISTIC_READ); + } + + @Lock(LockMode.PESSIMISTIC_WRITE) + @Query + private void queryMethodWithWriteLock() {} + + @Lock(LockMode.PESSIMISTIC_READ) + @Query + private void queryMethodWithReadLock() {} + @Query(value = QUERY, rowMapperClass = CustomRowMapper.class) private void queryMethod() {} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java index b0f5bf4a02..eded809c00 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,8 @@ import org.springframework.data.relational.core.mapping.Embedded; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; +import org.springframework.data.relational.core.sql.In; +import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.Repository; @@ -58,6 +60,7 @@ * @author Mark Paluch * @author Jens Schauder * @author Myeonghyeon Lee + * @author Diego Krupitza */ @ExtendWith(MockitoExtension.class) public class PartTreeJdbcQueryUnitTests { @@ -85,7 +88,7 @@ public void createQueryByAggregateReference() throws Exception { PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod); Hobby hobby = new Hobby(); hobby.name = "twentythree"; - ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] {hobby}), returnedType); + ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { hobby }), returnedType); assertSoftly(softly -> { @@ -96,6 +99,47 @@ public void createQueryByAggregateReference() throws Exception { }); } + @Test // GH-922 + void createQueryWithPessimisticWriteLock() throws Exception { + + JdbcQueryMethod queryMethod = getQueryMethod("findAllByFirstNameAndLastName", String.class, String.class); + PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod); + + String firstname = "Diego"; + String lastname = "Krupitza"; + ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { firstname, lastname }), + returnedType); + + assertSoftly(softly -> { + + softly.assertThat(query.getQuery().toUpperCase()).endsWith("FOR UPDATE"); + + softly.assertThat(query.getParameterSource().getValue("first_name")).isEqualTo(firstname); + softly.assertThat(query.getParameterSource().getValue("last_name")).isEqualTo(lastname); + }); + } + + @Test // GH-922 + void createQueryWithPessimisticReadLock() throws Exception { + + JdbcQueryMethod queryMethod = getQueryMethod("findAllByFirstNameAndAge", String.class, Integer.class); + PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod); + + String firstname = "Diego"; + Integer age = 22; + ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { firstname, age }), + returnedType); + + assertSoftly(softly -> { + + // this is also for update since h2 dialect does not distinguish between lockmodes + softly.assertThat(query.getQuery().toUpperCase()).endsWith("FOR UPDATE"); + + softly.assertThat(query.getParameterSource().getValue("first_name")).isEqualTo(firstname); + softly.assertThat(query.getParameterSource().getValue("age")).isEqualTo(age); + }); + } + @Test // DATAJDBC-318 public void shouldFailForQueryByList() throws Exception { @@ -116,7 +160,7 @@ public void createQueryForQueryByAggregateReference() throws Exception { JdbcQueryMethod queryMethod = getQueryMethod("findViaReferenceByHobbyReference", AggregateReference.class); PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod); AggregateReference hobby = AggregateReference.to("twentythree"); - ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] {hobby}), returnedType); + ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { hobby }), returnedType); assertSoftly(softly -> { @@ -133,7 +177,7 @@ public void createQueryForQueryByAggregateReferenceId() throws Exception { JdbcQueryMethod queryMethod = getQueryMethod("findViaIdByHobbyReference", String.class); PartTreeJdbcQuery jdbcQuery = createQuery(queryMethod); String hobby = "twentythree"; - ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] {hobby}), returnedType); + ParametrizedQuery query = jdbcQuery.createQuery(getAccessor(queryMethod, new Object[] { hobby }), returnedType); assertSoftly(softly -> { @@ -213,7 +257,6 @@ public void createsQueryToFindAllEntitiesByOneOfTwoStringAttributes() throws Exc + ".\"FIRST_NAME\" = :first_name)"); } - @Test // DATAJDBC-318 public void createsQueryToFindAllEntitiesByDateAttributeBetween() throws Exception { @@ -644,6 +687,12 @@ private RelationalParametersParameterAccessor getAccessor(JdbcQueryMethod queryM @NoRepositoryBean interface UserRepository extends Repository { + @Lock(LockMode.PESSIMISTIC_WRITE) + List findAllByFirstNameAndLastName(String firstName, String lastName); + + @Lock(LockMode.PESSIMISTIC_READ) + List findAllByFirstNameAndAge(String firstName, Integer age); + List findAllByFirstName(String firstName); List findAllByHated(Hobby hobby); @@ -758,7 +807,6 @@ static class AnotherEmbedded { } static class Hobby { - @Id - String name; + @Id String name; } } From cd3d0b19b080f08de49d6c0b82f6f535f2a423f5 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 9 Feb 2022 16:16:49 +0100 Subject: [PATCH 20/51] Polishing. Refactored the unit tests to include a negative case and to separate the different scenarios tested. Removed the default LockMode from the Lock annotation. I have the feeling that most users will assume an exclusive Lock when none is specified, but also don't want to request stronger locks than required. Original pull request #1158 See #1041 --- .../data/jdbc/repository/query/Lock.java | 2 +- .../JdbcRepositoryIntegrationTests.java | 1 + .../query/JdbcQueryMethodUnitTests.java | 22 ++++++++++--------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java index 0ef95ca0fb..1fd310b85f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java @@ -34,6 +34,6 @@ /** * Defines which type of {@link LockMode} we want to use. */ - LockMode value() default LockMode.PESSIMISTIC_READ; + LockMode value(); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 70391a68a2..048a78a5dc 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -335,6 +335,7 @@ public void findAllByQueryName() { @Test void findAllByFirstnameWithLock() { + DummyEntity dummyEntity = createDummyEntity(); repository.save(dummyEntity); assertThat(repository.findAllByName(dummyEntity.getName())).hasSize(1); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java index d30a3cdb24..a707f854a4 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.relational.core.sql.LockMode; @@ -123,28 +122,31 @@ public void returnsNullIfNoQueryIsFound() throws NoSuchMethodException { } @Test // GH-1041 - void returnsQueryMethodWithLock() throws NoSuchMethodException { + void returnsQueryMethodWithCorrectLockTypeWriteLock() throws NoSuchMethodException { JdbcQueryMethod queryMethodWithWriteLock = createJdbcQueryMethod("queryMethodWithWriteLock"); - JdbcQueryMethod queryMethodWithReadLock = createJdbcQueryMethod("queryMethodWithReadLock"); - assertThat(queryMethodWithWriteLock.hasLockMode()).isTrue(); - assertThat(queryMethodWithReadLock.hasLockMode()).isTrue(); + assertThat(queryMethodWithWriteLock.lookupLockAnnotation()).isPresent(); + assertThat(queryMethodWithWriteLock.lookupLockAnnotation().get().value()).isEqualTo(LockMode.PESSIMISTIC_WRITE); } @Test // GH-1041 - void returnsQueryMethodWithCorrectLockType() throws NoSuchMethodException { + void returnsQueryMethodWithCorrectLockTypeReadLock() throws NoSuchMethodException { - JdbcQueryMethod queryMethodWithWriteLock = createJdbcQueryMethod("queryMethodWithWriteLock"); JdbcQueryMethod queryMethodWithReadLock = createJdbcQueryMethod("queryMethodWithReadLock"); - assertThat(queryMethodWithWriteLock.lookupLockAnnotation()).isPresent(); assertThat(queryMethodWithReadLock.lookupLockAnnotation()).isPresent(); - - assertThat(queryMethodWithWriteLock.lookupLockAnnotation().get().value()).isEqualTo(LockMode.PESSIMISTIC_WRITE); assertThat(queryMethodWithReadLock.lookupLockAnnotation().get().value()).isEqualTo(LockMode.PESSIMISTIC_READ); } + @Test // GH-1041 + void returnsQueryMethodWithCorrectLockTypeNoLock() throws NoSuchMethodException { + + JdbcQueryMethod queryMethodWithWriteLock = createJdbcQueryMethod("queryMethodName"); + + assertThat(queryMethodWithWriteLock.lookupLockAnnotation()).isEmpty(); + } + @Lock(LockMode.PESSIMISTIC_WRITE) @Query private void queryMethodWithWriteLock() {} From e8c933dc80b8a4de50b63fd4edc5edfb22f7b9a1 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 11 Feb 2022 08:56:19 +0100 Subject: [PATCH 21/51] Polishing. Adding references to issues on test annotations. Made test methods package private. See #1164 --- ...sistentPropertyPathExtensionUnitTests.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java index 542aee09cf..562d36690d 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java @@ -38,8 +38,8 @@ public class PersistentPropertyPathExtensionUnitTests { JdbcMappingContext context = new JdbcMappingContext(); private RelationalPersistentEntity entity = context.getRequiredPersistentEntity(DummyEntity.class); - @Test - public void isEmbedded() { + @Test // DATAJDBC-340 + void isEmbedded() { assertSoftly(softly -> { @@ -49,8 +49,8 @@ public void isEmbedded() { }); } - @Test - public void isMultiValued() { + @Test // DATAJDBC-340 + void isMultiValued() { assertSoftly(softly -> { @@ -62,8 +62,8 @@ public void isMultiValued() { }); } - @Test - public void leafEntity() { + @Test // DATAJDBC-340 + void leafEntity() { RelationalPersistentEntity second = context.getRequiredPersistentEntity(Second.class); RelationalPersistentEntity third = context.getRequiredPersistentEntity(Third.class); @@ -78,8 +78,8 @@ public void leafEntity() { }); } - @Test - public void isEntity() { + @Test // DATAJDBC-340 + void isEntity() { assertSoftly(softly -> { @@ -94,8 +94,8 @@ public void isEntity() { }); } - @Test - public void getTableName() { + @Test // DATAJDBC-340 + void getTableName() { assertSoftly(softly -> { @@ -109,8 +109,8 @@ public void getTableName() { }); } - @Test - public void getTableAlias() { + @Test // DATAJDBC-340 + void getTableAlias() { assertSoftly(softly -> { @@ -129,8 +129,8 @@ public void getTableAlias() { }); } - @Test - public void getColumnName() { + @Test // DATAJDBC-340 + void getColumnName() { assertSoftly(softly -> { @@ -144,7 +144,7 @@ public void getColumnName() { } @Test // DATAJDBC-359 - public void idDefiningPath() { + void idDefiningPath() { assertSoftly(softly -> { @@ -160,7 +160,7 @@ public void idDefiningPath() { } @Test // DATAJDBC-359 - public void reverseColumnName() { + void reverseColumnName() { assertSoftly(softly -> { @@ -177,7 +177,7 @@ public void reverseColumnName() { } @Test // DATAJDBC-359 - public void getRequiredIdProperty() { + void getRequiredIdProperty() { assertSoftly(softly -> { @@ -189,7 +189,7 @@ public void getRequiredIdProperty() { } @Test // DATAJDBC-359 - public void extendBy() { + void extendBy() { assertSoftly(softly -> { From e84a34a507d406eaf99e043f897b3ad54a16b764 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 11 Feb 2022 09:08:00 +0100 Subject: [PATCH 22/51] Fixes NPE in PersistentPropertyPathExtension.equals. Closes #1164 --- ...sistentPropertyPathExtensionUnitTests.java | 20 +++++++++++++++++++ .../PersistentPropertyPathExtension.java | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java index 562d36690d..be07ab8a6b 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/PersistentPropertyPathExtensionUnitTests.java @@ -200,6 +200,26 @@ void extendBy() { }); } + @Test // GH--1164 + void equalsWorks() { + + PersistentPropertyPathExtension root1 = extPath(entity); + PersistentPropertyPathExtension root2 = extPath(entity); + PersistentPropertyPathExtension path1 = extPath("withId"); + PersistentPropertyPathExtension path2 = extPath("withId"); + + assertSoftly(softly -> { + + softly.assertThat(root1).describedAs("root is equal to self").isEqualTo(root1); + softly.assertThat(root2).describedAs("root is equal to identical root").isEqualTo(root1); + softly.assertThat(path1).describedAs("path is equal to self").isEqualTo(path1); + softly.assertThat(path2).describedAs("path is equal to identical path").isEqualTo(path1); + softly.assertThat(path1).describedAs("path is not equal to other path").isNotEqualTo(extPath("entityId")); + softly.assertThat(root1).describedAs("root is not equal to path").isNotEqualTo(path1); + softly.assertThat(path1).describedAs("path is not equal to root").isNotEqualTo(root1); + }); + } + private PersistentPropertyPathExtension extPath(RelationalPersistentEntity entity) { return new PersistentPropertyPathExtension(context, entity); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java index e06ebcdbef..2c5b19f0ab 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java @@ -442,7 +442,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; PersistentPropertyPathExtension that = (PersistentPropertyPathExtension) o; return entity.equals(that.entity) && - path.equals(that.path); + Objects.equals(path, that.path); } @Override From f7887f8626e8d88db52c04b00e24a9db8bc2f040 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 12 Feb 2022 12:45:09 +0100 Subject: [PATCH 23/51] Added reference documentation for Lock on derived queries. The reference documentation now contains how to use `@Lock` on derived queries and what to expect from it. Original pull request #1166 --- src/main/asciidoc/jdbc.adoc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/asciidoc/jdbc.adoc b/src/main/asciidoc/jdbc.adoc index 83b53ac4c3..1fecabb4d0 100644 --- a/src/main/asciidoc/jdbc.adoc +++ b/src/main/asciidoc/jdbc.adoc @@ -1046,3 +1046,32 @@ class Config { If you expose a bean of type `AuditorAware` to the `ApplicationContext`, the auditing infrastructure automatically picks it up and uses it to determine the current user to be set on domain types. If you have multiple implementations registered in the `ApplicationContext`, you can select the one to be used by explicitly setting the `auditorAwareRef` attribute of `@EnableJdbcAuditing`. + +[[jdbc.locking]] +== JDBC Locking + +Spring Data JDBC currently supports locking on derived query methods. To enable locking on a given derived query method inside a repository, you just need to add the `@Lock` annotation above it. + +.Using @Lock on derived query method +==== +[source,java] +---- +interface UserRepository extends CrudRepository { + + @Lock(LockMode.PESSIMISTIC_READ) + List findByLastname(String lastname); +} +---- +==== + +As you can see above, the method `findByLastname(String lastname)` will be executed with a pessimistic read lock. If you are using a databse with the MySQL Dialect this will result for example in the following query: + +.Resulting Sql query for MySQL dialect +==== +[source,sql] +---- +Select * from user u where u.lastname = lastname LOCK IN SHARE MODE +---- +==== + +Alternative to `LockMode.PESSIMISTIC_READ` you can use `LockMode.PESSIMISTIC_WRITE`. \ No newline at end of file From 1456788d775e6881cd456e5485b4eb0a47b5385c Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 15 Feb 2022 11:36:01 +0100 Subject: [PATCH 24/51] Polishing. Original pull request #1166 --- src/main/asciidoc/jdbc.adoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/asciidoc/jdbc.adoc b/src/main/asciidoc/jdbc.adoc index 1fecabb4d0..f9993ccd69 100644 --- a/src/main/asciidoc/jdbc.adoc +++ b/src/main/asciidoc/jdbc.adoc @@ -1050,7 +1050,11 @@ If you have multiple implementations registered in the `ApplicationContext`, you [[jdbc.locking]] == JDBC Locking -Spring Data JDBC currently supports locking on derived query methods. To enable locking on a given derived query method inside a repository, you just need to add the `@Lock` annotation above it. +Spring Data JDBC supports locking on derived query methods. +To enable locking on a given derived query method inside a repository, you annotate it with `@Lock`. +The required value of type `LockMode` offers two values: `PESSIMISTIC_READ` which guarantees that the data you are reading doesn't get modified and `PESSIMISTIC_WRITE` which obtains a lock to modify the data. +Some databases do not make this distinction. +In that cases both modes are equivalent of `PESSIMISTIC_WRITE`. .Using @Lock on derived query method ==== From d4c223d9d5a5dde3e3b6381033ee4c4f891eb1a4 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Tue, 15 Feb 2022 15:12:58 +0100 Subject: [PATCH 25/51] Adapt to changes in entity creation metadata APIs in Spring Data Commons. --- .../jdbc/core/convert/BasicJdbcConverter.java | 8 +- .../jdbc/core/mapping/JdbcMappingContext.java | 10 +- .../repository/query/JdbcQueryExecution.java | 2 +- .../conversion/BasicRelationalConverter.java | 2 +- .../core/conversion/RelationalConverter.java | 2 +- .../query/DtoInstantiatingConverter.java | 104 ------------------ 6 files changed, 12 insertions(+), 116 deletions(-) delete mode 100755 spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java index 0898c0ca70..6375ee038f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java @@ -25,16 +25,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.convert.ConverterNotFoundException; -import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.CustomConversions; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.data.jdbc.core.mapping.JdbcValue; import org.springframework.data.jdbc.support.JdbcUtil; +import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PreferredConstructor; @@ -181,6 +180,7 @@ public SQLType getTargetSqlType(RelationalPersistentProperty property) { public int getSqlType(RelationalPersistentProperty property) { return JdbcUtil.sqlTypeFor(getColumnType(property)); } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.convert.JdbcConverter#getColumnType(org.springframework.data.relational.core.mapping.RelationalPersistentProperty) @@ -621,7 +621,7 @@ public ResultSetParameterValueProvider(@Nullable Object idValue, RelationalPersi */ @Override @Nullable - public T getParameterValue(PreferredConstructor.Parameter parameter) { + public T getParameterValue(Parameter parameter) { String parameterName = parameter.getName(); @@ -642,7 +642,7 @@ enum NoOpParameterValueProvider implements ParameterValueProvider T getParameterValue(PreferredConstructor.Parameter parameter) { + public T getParameterValue(Parameter parameter) { return null; } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java index f5a9f6f785..179ca64cd6 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java @@ -15,8 +15,8 @@ */ package org.springframework.data.jdbc.core.mapping; -import org.springframework.data.mapping.PreferredConstructor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; +import org.springframework.data.mapping.InstanceCreatorMetadata; +import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; @@ -67,13 +67,13 @@ public JdbcMappingContext(NamingStrategy namingStrategy) { protected RelationalPersistentEntity createPersistentEntity(TypeInformation typeInformation) { RelationalPersistentEntity entity = super.createPersistentEntity(typeInformation); - PreferredConstructor constructor = entity.getPersistenceConstructor(); + InstanceCreatorMetadata creator = entity.getInstanceCreatorMetadata(); - if (constructor == null) { + if (creator == null) { return entity; } - for (Parameter parameter : constructor.getParameters()) { + for (Parameter parameter : creator.getParameters()) { Assert.state(StringUtils.hasText(parameter.getName()), () -> String.format(MISSING_PARAMETER_NAME, parameter)); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryExecution.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryExecution.java index 4199c275ff..d8e9633f6c 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryExecution.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryExecution.java @@ -16,11 +16,11 @@ package org.springframework.data.jdbc.repository.query; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.DtoInstantiatingConverter; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.EntityInstantiators; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; -import org.springframework.data.relational.repository.query.DtoInstantiatingConverter; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.util.Lazy; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java index 0bfcdc7386..46dc9d3262 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/BasicRelationalConverter.java @@ -27,10 +27,10 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.CustomConversions.StoreConversions; +import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.EntityInstantiators; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java index 707eb824e6..489e31df70 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java @@ -18,9 +18,9 @@ import java.util.function.Function; import org.springframework.core.convert.ConversionService; +import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.EntityInstantiators; import org.springframework.data.mapping.model.ParameterValueProvider; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java deleted file mode 100755 index 2f3218aa9f..0000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed 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 - * - * https://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.springframework.data.relational.repository.query; - -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PreferredConstructor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; -import org.springframework.data.mapping.SimplePropertyHandler; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.EntityInstantiator; -import org.springframework.data.mapping.model.EntityInstantiators; -import org.springframework.data.mapping.model.ParameterValueProvider; -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; -import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; -import org.springframework.util.Assert; - -/** - * {@link Converter} to instantiate DTOs from fully equipped domain objects. - * - * @author Mark Paluch - */ -public class DtoInstantiatingConverter implements Converter { - - private final Class targetType; - private final MappingContext, ? extends PersistentProperty> context; - private final EntityInstantiator instantiator; - - /** - * Creates a new {@link Converter} to instantiate DTOs. - * - * @param dtoType must not be {@literal null}. - * @param context must not be {@literal null}. - * @param instantiator must not be {@literal null}. - */ - public DtoInstantiatingConverter(Class dtoType, - MappingContext, ? extends RelationalPersistentProperty> context, - EntityInstantiators instantiator) { - - Assert.notNull(dtoType, "DTO type must not be null!"); - Assert.notNull(context, "MappingContext must not be null!"); - Assert.notNull(instantiator, "EntityInstantiators must not be null!"); - - this.targetType = dtoType; - this.context = context; - this.instantiator = instantiator.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType)); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) - */ - @Override - public Object convert(Object source) { - - if (targetType.isInterface()) { - return source; - } - - final PersistentEntity sourceEntity = context.getRequiredPersistentEntity(source.getClass()); - final PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); - final PersistentEntity targetEntity = context.getRequiredPersistentEntity(targetType); - final PreferredConstructor> constructor = targetEntity - .getPersistenceConstructor(); - - @SuppressWarnings({"rawtypes", "unchecked"}) - Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() { - - @Override - public Object getParameterValue(Parameter parameter) { - return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName())); - } - }); - - final PersistentPropertyAccessor dtoAccessor = targetEntity.getPropertyAccessor(dto); - - targetEntity.doWithProperties((SimplePropertyHandler) property -> { - - if (constructor.isConstructorParameter(property)) { - return; - } - - dtoAccessor.setProperty(property, - sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName()))); - }); - - return dto; - } -} From 4d21e565488bf7d32ff7457feebce192c8f21d6d Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Tue, 15 Feb 2022 08:59:49 -0600 Subject: [PATCH 26/51] Update CI properties. See #1133 --- ci/pipeline.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/pipeline.properties b/ci/pipeline.properties index 9d382ca66b..b3314cdc63 100644 --- a/ci/pipeline.properties +++ b/ci/pipeline.properties @@ -4,9 +4,9 @@ java.next.tag=11.0.13_8-jdk java.lts.tag=17.0.1_12-jdk # Docker container images - standard -docker.java.main.image=eclipse-temurin:${java.main.tag} -docker.java.next.image=eclipse-temurin:${java.next.tag} -docker.java.lts.image=eclipse-temurin:${java.lts.tag} +docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag} +docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag} +docker.java.lts.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.lts.tag} # Supported versions of MongoDB docker.mongodb.4.0.version=4.0.23 From 4a8b185b02d28ed419c26856e82187b363c23830 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 17 Feb 2022 13:50:23 +0100 Subject: [PATCH 27/51] Update copyright year to 2022. See: #1168 --- .../data/relational/core/conversion/AggregateChange.java | 2 +- .../data/relational/core/conversion/DbAction.java | 2 +- .../core/conversion/DbActionExecutionException.java | 2 +- .../relational/core/conversion/DbActionExecutionResult.java | 2 +- .../relational/core/conversion/DefaultAggregateChange.java | 2 +- .../relational/core/conversion/MutableAggregateChange.java | 2 +- .../data/relational/core/conversion/PathNode.java | 2 +- .../data/relational/core/conversion/RelationalConverter.java | 2 +- .../core/conversion/RelationalEntityDeleteWriter.java | 2 +- .../core/conversion/RelationalEntityInsertWriter.java | 2 +- .../core/conversion/RelationalEntityUpdateWriter.java | 2 +- .../core/conversion/RelationalEntityVersionUtils.java | 2 +- .../relational/core/conversion/RelationalEntityWriter.java | 2 +- .../data/relational/core/conversion/WritingContext.java | 2 +- .../data/relational/core/dialect/AnsiDialect.java | 2 +- .../data/relational/core/dialect/ArrayColumns.java | 2 +- .../data/relational/core/dialect/Db2Dialect.java | 2 +- .../springframework/data/relational/core/dialect/Escaper.java | 2 +- .../data/relational/core/dialect/H2Dialect.java | 2 +- .../data/relational/core/dialect/HsqlDbDialect.java | 2 +- .../data/relational/core/dialect/IdGeneration.java | 2 +- .../data/relational/core/dialect/LimitClause.java | 2 +- .../data/relational/core/dialect/LockClause.java | 2 +- .../data/relational/core/dialect/MariaDbDialect.java | 2 +- .../data/relational/core/dialect/MySqlDialect.java | 2 +- .../data/relational/core/dialect/OracleDialect.java | 2 +- .../data/relational/core/dialect/OrderByNullPrecedence.java | 2 +- .../data/relational/core/dialect/PostgresDialect.java | 2 +- .../data/relational/core/dialect/RenderContextFactory.java | 2 +- .../data/relational/core/dialect/SqlServerDialect.java | 2 +- .../relational/core/dialect/SqlServerSelectRenderContext.java | 2 +- .../core/dialect/TimestampAtUtcToOffsetDateTimeConverter.java | 2 +- .../core/mapping/BasicRelationalPersistentProperty.java | 2 +- .../data/relational/core/mapping/CachingNamingStrategy.java | 2 +- .../springframework/data/relational/core/mapping/Column.java | 2 +- .../data/relational/core/mapping/DerivedSqlIdentifier.java | 2 +- .../data/relational/core/mapping/Embedded.java | 2 +- .../data/relational/core/mapping/MappedCollection.java | 2 +- .../data/relational/core/mapping/NamingStrategy.java | 2 +- .../core/mapping/PersistentPropertyPathExtension.java | 2 +- .../relational/core/mapping/RelationalMappingContext.java | 2 +- .../relational/core/mapping/RelationalPersistentEntity.java | 2 +- .../core/mapping/RelationalPersistentEntityImpl.java | 2 +- .../relational/core/mapping/RelationalPersistentProperty.java | 2 +- .../springframework/data/relational/core/mapping/Table.java | 4 ++-- .../core/mapping/event/AbstractRelationalEvent.java | 2 +- .../core/mapping/event/AbstractRelationalEventListener.java | 2 +- .../relational/core/mapping/event/AfterConvertCallback.java | 2 +- .../data/relational/core/mapping/event/AfterConvertEvent.java | 2 +- .../relational/core/mapping/event/AfterDeleteCallback.java | 2 +- .../data/relational/core/mapping/event/AfterDeleteEvent.java | 2 +- .../data/relational/core/mapping/event/AfterLoadCallback.java | 2 +- .../data/relational/core/mapping/event/AfterLoadEvent.java | 2 +- .../data/relational/core/mapping/event/AfterSaveCallback.java | 2 +- .../data/relational/core/mapping/event/AfterSaveEvent.java | 2 +- .../relational/core/mapping/event/BeforeConvertCallback.java | 2 +- .../relational/core/mapping/event/BeforeConvertEvent.java | 2 +- .../relational/core/mapping/event/BeforeDeleteCallback.java | 2 +- .../data/relational/core/mapping/event/BeforeDeleteEvent.java | 2 +- .../relational/core/mapping/event/BeforeSaveCallback.java | 2 +- .../data/relational/core/mapping/event/BeforeSaveEvent.java | 2 +- .../data/relational/core/mapping/event/Identifier.java | 2 +- .../core/mapping/event/RelationalAuditingCallback.java | 2 +- .../relational/core/mapping/event/RelationalDeleteEvent.java | 2 +- .../data/relational/core/mapping/event/RelationalEvent.java | 2 +- .../core/mapping/event/RelationalEventWithEntity.java | 2 +- .../relational/core/mapping/event/RelationalSaveEvent.java | 2 +- .../relational/core/mapping/event/WithAggregateChange.java | 2 +- .../data/relational/core/mapping/event/WithEntity.java | 2 +- .../data/relational/core/mapping/event/WithId.java | 2 +- .../springframework/data/relational/core/query/Criteria.java | 2 +- .../data/relational/core/query/CriteriaDefinition.java | 2 +- .../org/springframework/data/relational/core/query/Query.java | 2 +- .../springframework/data/relational/core/query/Update.java | 2 +- .../data/relational/core/query/ValueFunction.java | 2 +- .../data/relational/core/sql/AbstractImportValidator.java | 2 +- .../data/relational/core/sql/AbstractSegment.java | 2 +- .../org/springframework/data/relational/core/sql/Aliased.java | 2 +- .../data/relational/core/sql/AliasedExpression.java | 2 +- .../data/relational/core/sql/AnalyticFunction.java | 2 +- .../data/relational/core/sql/AndCondition.java | 2 +- .../springframework/data/relational/core/sql/AssignValue.java | 2 +- .../springframework/data/relational/core/sql/Assignment.java | 2 +- .../springframework/data/relational/core/sql/Assignments.java | 2 +- .../data/relational/core/sql/AsteriskFromTable.java | 2 +- .../org/springframework/data/relational/core/sql/Between.java | 2 +- .../springframework/data/relational/core/sql/BindMarker.java | 2 +- .../data/relational/core/sql/BooleanLiteral.java | 2 +- .../org/springframework/data/relational/core/sql/Cast.java | 2 +- .../org/springframework/data/relational/core/sql/Column.java | 2 +- .../springframework/data/relational/core/sql/Comparison.java | 2 +- .../data/relational/core/sql/CompositeSqlIdentifier.java | 2 +- .../springframework/data/relational/core/sql/Condition.java | 2 +- .../springframework/data/relational/core/sql/Conditions.java | 2 +- .../data/relational/core/sql/ConstantCondition.java | 2 +- .../data/relational/core/sql/DefaultDelete.java | 2 +- .../data/relational/core/sql/DefaultDeleteBuilder.java | 2 +- .../data/relational/core/sql/DefaultIdentifierProcessing.java | 2 +- .../data/relational/core/sql/DefaultInsert.java | 2 +- .../data/relational/core/sql/DefaultInsertBuilder.java | 2 +- .../data/relational/core/sql/DefaultSelect.java | 2 +- .../data/relational/core/sql/DefaultSelectBuilder.java | 2 +- .../data/relational/core/sql/DefaultSqlIdentifier.java | 2 +- .../data/relational/core/sql/DefaultUpdate.java | 2 +- .../data/relational/core/sql/DefaultUpdateBuilder.java | 2 +- .../org/springframework/data/relational/core/sql/Delete.java | 2 +- .../data/relational/core/sql/DeleteBuilder.java | 2 +- .../data/relational/core/sql/DeleteValidator.java | 2 +- .../springframework/data/relational/core/sql/Expression.java | 2 +- .../springframework/data/relational/core/sql/Expressions.java | 2 +- .../data/relational/core/sql/FalseCondition.java | 2 +- .../org/springframework/data/relational/core/sql/From.java | 2 +- .../springframework/data/relational/core/sql/Functions.java | 2 +- .../data/relational/core/sql/IdentifierProcessing.java | 2 +- .../java/org/springframework/data/relational/core/sql/In.java | 2 +- .../springframework/data/relational/core/sql/InlineQuery.java | 2 +- .../org/springframework/data/relational/core/sql/Insert.java | 2 +- .../data/relational/core/sql/InsertBuilder.java | 2 +- .../org/springframework/data/relational/core/sql/Into.java | 2 +- .../org/springframework/data/relational/core/sql/IsNull.java | 2 +- .../org/springframework/data/relational/core/sql/Join.java | 2 +- .../org/springframework/data/relational/core/sql/Like.java | 2 +- .../org/springframework/data/relational/core/sql/Literal.java | 2 +- .../springframework/data/relational/core/sql/LockMode.java | 2 +- .../springframework/data/relational/core/sql/LockOptions.java | 2 +- .../data/relational/core/sql/MultipleCondition.java | 2 +- .../org/springframework/data/relational/core/sql/Named.java | 2 +- .../data/relational/core/sql/NestedCondition.java | 2 +- .../org/springframework/data/relational/core/sql/Not.java | 2 +- .../data/relational/core/sql/NumericLiteral.java | 2 +- .../springframework/data/relational/core/sql/OrCondition.java | 2 +- .../org/springframework/data/relational/core/sql/OrderBy.java | 2 +- .../data/relational/core/sql/OrderByField.java | 2 +- .../org/springframework/data/relational/core/sql/SQL.java | 2 +- .../org/springframework/data/relational/core/sql/Segment.java | 2 +- .../springframework/data/relational/core/sql/SegmentList.java | 2 +- .../org/springframework/data/relational/core/sql/Select.java | 2 +- .../data/relational/core/sql/SelectBuilder.java | 2 +- .../springframework/data/relational/core/sql/SelectList.java | 2 +- .../data/relational/core/sql/SelectValidator.java | 2 +- .../data/relational/core/sql/SimpleCondition.java | 2 +- .../data/relational/core/sql/SimpleFunction.java | 2 +- .../data/relational/core/sql/SimpleSegment.java | 2 +- .../data/relational/core/sql/SqlIdentifier.java | 2 +- .../data/relational/core/sql/StatementBuilder.java | 2 +- .../data/relational/core/sql/StringLiteral.java | 2 +- .../data/relational/core/sql/SubselectExpression.java | 2 +- .../org/springframework/data/relational/core/sql/Table.java | 2 +- .../springframework/data/relational/core/sql/TableLike.java | 2 +- .../data/relational/core/sql/TrueCondition.java | 2 +- .../org/springframework/data/relational/core/sql/Update.java | 2 +- .../data/relational/core/sql/UpdateBuilder.java | 2 +- .../org/springframework/data/relational/core/sql/Values.java | 2 +- .../springframework/data/relational/core/sql/Visitable.java | 2 +- .../org/springframework/data/relational/core/sql/Visitor.java | 2 +- .../org/springframework/data/relational/core/sql/Where.java | 2 +- .../relational/core/sql/render/AnalyticFunctionVisitor.java | 2 +- .../data/relational/core/sql/render/AssignmentVisitor.java | 2 +- .../data/relational/core/sql/render/BetweenVisitor.java | 2 +- .../data/relational/core/sql/render/CastVisitor.java | 2 +- .../data/relational/core/sql/render/ColumnVisitor.java | 2 +- .../data/relational/core/sql/render/ComparisonVisitor.java | 2 +- .../data/relational/core/sql/render/ConditionVisitor.java | 2 +- .../relational/core/sql/render/ConstantConditionVisitor.java | 2 +- .../data/relational/core/sql/render/DelegatingVisitor.java | 2 +- .../relational/core/sql/render/DeleteStatementVisitor.java | 2 +- .../data/relational/core/sql/render/EmptyInVisitor.java | 2 +- .../data/relational/core/sql/render/ExpressionVisitor.java | 2 +- .../core/sql/render/FilteredSingleConditionRenderSupport.java | 2 +- .../relational/core/sql/render/FilteredSubtreeVisitor.java | 2 +- .../data/relational/core/sql/render/FromClauseVisitor.java | 2 +- .../data/relational/core/sql/render/FromTableVisitor.java | 2 +- .../data/relational/core/sql/render/InVisitor.java | 2 +- .../relational/core/sql/render/InsertStatementVisitor.java | 2 +- .../data/relational/core/sql/render/IntoClauseVisitor.java | 2 +- .../data/relational/core/sql/render/IsNullVisitor.java | 2 +- .../data/relational/core/sql/render/JoinVisitor.java | 2 +- .../data/relational/core/sql/render/LikeVisitor.java | 2 +- .../core/sql/render/MultiConcatConditionVisitor.java | 2 +- .../data/relational/core/sql/render/NameRenderer.java | 2 +- .../data/relational/core/sql/render/NamingStrategies.java | 2 +- .../relational/core/sql/render/NestedConditionVisitor.java | 2 +- .../data/relational/core/sql/render/PartRenderer.java | 2 +- .../data/relational/core/sql/render/RenderContext.java | 2 +- .../data/relational/core/sql/render/RenderNamingStrategy.java | 2 +- .../data/relational/core/sql/render/RenderTarget.java | 2 +- .../data/relational/core/sql/render/Renderer.java | 2 +- .../data/relational/core/sql/render/SegmentListVisitor.java | 2 +- .../data/relational/core/sql/render/SelectListVisitor.java | 2 +- .../relational/core/sql/render/SelectStatementVisitor.java | 2 +- .../relational/core/sql/render/SimpleFunctionVisitor.java | 2 +- .../data/relational/core/sql/render/SimpleRenderContext.java | 2 +- .../data/relational/core/sql/render/SqlRenderer.java | 2 +- .../core/sql/render/TypedSingleConditionRenderSupport.java | 2 +- .../data/relational/core/sql/render/TypedSubtreeVisitor.java | 2 +- .../relational/core/sql/render/UpdateStatementVisitor.java | 2 +- .../data/relational/core/sql/render/ValuesVisitor.java | 2 +- .../data/relational/core/sql/render/WhereClauseVisitor.java | 2 +- .../data/relational/repository/query/CriteriaFactory.java | 2 +- .../data/relational/repository/query/ParameterMetadata.java | 2 +- .../repository/query/ParameterMetadataProvider.java | 2 +- .../repository/query/RelationalEntityInformation.java | 2 +- .../relational/repository/query/RelationalEntityMetadata.java | 2 +- .../relational/repository/query/RelationalExampleMapper.java | 2 +- .../repository/query/RelationalParameterAccessor.java | 2 +- .../relational/repository/query/RelationalParameters.java | 2 +- .../query/RelationalParametersParameterAccessor.java | 2 +- .../relational/repository/query/RelationalQueryCreator.java | 2 +- .../repository/query/SimpleRelationalEntityMetadata.java | 2 +- .../support/MappingRelationalEntityInformation.java | 2 +- .../data/relational/core/query/CriteriaStepExtensions.kt | 2 +- .../core/conversion/DbActionExecutionExceptionUnitTests.java | 2 +- .../data/relational/core/conversion/DbActionTestSupport.java | 2 +- .../conversion/RelationalEntityDeleteWriterUnitTests.java | 2 +- .../conversion/RelationalEntityInsertWriterUnitTests.java | 2 +- .../conversion/RelationalEntityUpdateWriterUnitTests.java | 2 +- .../core/conversion/RelationalEntityWriterUnitTests.java | 2 +- .../data/relational/core/dialect/EscaperUnitTests.java | 2 +- .../data/relational/core/dialect/HsqlDbDialectUnitTests.java | 2 +- .../core/dialect/MySqlDialectRenderingUnitTests.java | 2 +- .../data/relational/core/dialect/MySqlDialectUnitTests.java | 2 +- .../relational/core/dialect/PostgresDialectUnitTests.java | 2 +- .../relational/core/dialect/SqlServerDialectUnitTests.java | 2 +- .../TimestampAtUtcToOffsetDateTimeConverterUnitTests.java | 2 +- .../mapping/BasicRelationalPersistentPropertyUnitTests.java | 2 +- .../core/mapping/DerivedSqlIdentifierUnitTests.java | 2 +- .../data/relational/core/mapping/NamingStrategyUnitTests.java | 2 +- .../core/mapping/RelationalMappingContextUnitTests.java | 2 +- .../core/mapping/RelationalPersistentEntityImplUnitTests.java | 2 +- .../event/AbstractRelationalEventListenerUnitTests.java | 2 +- .../data/relational/core/query/CriteriaUnitTests.java | 2 +- .../data/relational/core/query/QueryUnitTests.java | 2 +- .../data/relational/core/query/UpdateUnitTests.java | 2 +- .../data/relational/core/sql/AbstractSegmentTests.java | 2 +- .../data/relational/core/sql/AbstractTestSegment.java | 2 +- .../data/relational/core/sql/CapturingVisitor.java | 2 +- .../data/relational/core/sql/ConditionsUnitTests.java | 2 +- .../core/sql/DefaultIdentifierProcessingUnitTests.java | 2 +- .../data/relational/core/sql/DeleteBuilderUnitTests.java | 2 +- .../data/relational/core/sql/DeleteValidatorUnitTests.java | 2 +- .../org/springframework/data/relational/core/sql/InTests.java | 2 +- .../data/relational/core/sql/InsertBuilderUnitTests.java | 2 +- .../data/relational/core/sql/SelectBuilderUnitTests.java | 2 +- .../data/relational/core/sql/SelectValidatorUnitTests.java | 2 +- .../data/relational/core/sql/SqlIdentifierUnitTests.java | 2 +- .../springframework/data/relational/core/sql/TestFrom.java | 2 +- .../springframework/data/relational/core/sql/TestJoin.java | 2 +- .../data/relational/core/sql/UpdateBuilderUnitTests.java | 2 +- .../core/sql/render/ConditionRendererUnitTests.java | 2 +- .../relational/core/sql/render/DeleteRendererUnitTests.java | 2 +- .../core/sql/render/ExpressionVisitorUnitTests.java | 2 +- .../core/sql/render/FromClauseVisitorUnitTests.java | 2 +- .../relational/core/sql/render/InsertRendererUnitTests.java | 2 +- .../relational/core/sql/render/JoinVisitorTestsUnitTest.java | 2 +- .../relational/core/sql/render/NameRendererUnitTests.java | 2 +- .../core/sql/render/OrderByClauseVisitorUnitTests.java | 2 +- .../relational/core/sql/render/SelectRendererUnitTests.java | 2 +- .../core/sql/render/TypedSubtreeVisitorUnitTests.java | 2 +- .../relational/core/sql/render/UpdateRendererUnitTests.java | 2 +- .../data/relational/degraph/DependencyTests.java | 2 +- .../relational/repository/query/CriteriaFactoryUnitTests.java | 2 +- .../repository/query/ParameterMetadataProviderUnitTests.java | 2 +- .../repository/query/RelationalExampleMapperTests.java | 2 +- .../data/relational/core/query/CriteriaStepExtensionsTests.kt | 2 +- src/main/asciidoc/index.adoc | 2 +- 265 files changed, 266 insertions(+), 266 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java index 6b61901592..6afe39d55a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java index 126d1ad677..490c9771b2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionException.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionException.java index f5f7938bd0..d81fb72089 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionException.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionResult.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionResult.java index 0e4d8a4a62..b65165950a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionResult.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbActionExecutionResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java index 7c71a51469..5d84d33e84 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java index 8286628440..2df77a0e0c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/PathNode.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/PathNode.java index 859433b94c..d200a07be4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/PathNode.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/PathNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java index 489e31df70..2aaf3444a4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java index dc5658c174..46876968b9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriter.java index 423920ca45..169857fe38 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriter.java index 13bbac9dc2..e908fc4237 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityVersionUtils.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityVersionUtils.java index 0d0af62285..127f706cbc 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityVersionUtils.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityVersionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityWriter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityWriter.java index af6da1a571..cf3cd4c77a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityWriter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java index db64d79167..672e4bfa7e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AnsiDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AnsiDialect.java index 1d84c0c17b..1f398bfad2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AnsiDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/AnsiDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/ArrayColumns.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/ArrayColumns.java index 52c373a2f1..12b87229cf 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/ArrayColumns.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/ArrayColumns.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Db2Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Db2Dialect.java index 82f527a148..65620f7dc5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Db2Dialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Db2Dialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Escaper.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Escaper.java index 5f202b558a..c9657da47f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Escaper.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Escaper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/H2Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/H2Dialect.java index 7444edde27..daa39ed1a8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/H2Dialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/H2Dialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/HsqlDbDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/HsqlDbDialect.java index cf534de202..d34e86cdfb 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/HsqlDbDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/HsqlDbDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/IdGeneration.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/IdGeneration.java index 2e6d573cbd..a6e226f390 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/IdGeneration.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/IdGeneration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LimitClause.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LimitClause.java index 41f4912893..4d40da69b0 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LimitClause.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LimitClause.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LockClause.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LockClause.java index 55289e47df..a5c4cc8bb9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LockClause.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/LockClause.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MariaDbDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MariaDbDialect.java index c983b37bc4..44ace93c71 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MariaDbDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MariaDbDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java index ce05a21fe3..d447b9ffa7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/MySqlDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OracleDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OracleDialect.java index 90f7d466e7..20df1727b5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OracleDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OracleDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java index 3bc8d56ae1..d65482d9d1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2022-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java index 8782bbf3da..ceeba4431b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java index c9dcc065d0..a36bcc841c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/RenderContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java index b25335abd6..75a2be3fb7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerSelectRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerSelectRenderContext.java index d17bf53010..08fe0895da 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerSelectRenderContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerSelectRenderContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverter.java index 7ec957c951..a255fa6b84 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java index 4b5c300100..fc7ac4ea82 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/CachingNamingStrategy.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/CachingNamingStrategy.java index f289834e5e..8bd058a3d7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/CachingNamingStrategy.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/CachingNamingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Column.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Column.java index 1fe7229f26..21eef1ae05 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Column.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Column.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java index 2f3eadfeb8..4539f39d9a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java index d6e5c2572e..060a2c507f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java index 70f7e92a9f..a82ce1983e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/NamingStrategy.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/NamingStrategy.java index ecdcbdb7dd..f40b65e045 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/NamingStrategy.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/NamingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java index 2c5b19f0ab..dfb3f8ed21 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/PersistentPropertyPathExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java index 5056f143bd..f473d57555 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntity.java index 847ab40986..15b3234763 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntity.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java index e80c327162..32f81aea2e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java index 96fe88d03d..4965aba947 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Table.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Table.java index 19b4e21dcc..f85f68ea03 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Table.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Table.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,4 +59,4 @@ * The default schema itself can be provided by the means of {@link NamingStrategy#getSchema()} */ String schema() default ""; -} \ No newline at end of file +} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEvent.java index b93a584010..4426a054a6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListener.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListener.java index 14f046e4b0..5e4f45a8bd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListener.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertCallback.java index 28389a07d3..0c859f019f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertEvent.java index 2de9c71cab..561b76a384 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterConvertEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteCallback.java index 9ab856b613..d1708918a2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java index 38af43691e..19ea043824 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadCallback.java index 4f7589e20b..5b51c11cdd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java index 8c343ea72c..efa905fd69 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveCallback.java index 9820ef9544..e821232165 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java index 68ff56289d..0f7e22437a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertCallback.java index a61414347d..8a8ed2bf51 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java index 26fc9dcc73..19296453e7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java index f377246c5c..28f52d66b5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java index 860d22d26b..25f8f6f7fe 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java index 58cd75f1c8..da025c7e20 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java index 6e0db10463..d0deeda0c9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java index 82e9567c4f..c0a7413ae6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalAuditingCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalAuditingCallback.java index 6dd04acbb8..e29e5e25bc 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalAuditingCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalAuditingCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java index 5ec07367c0..cab8ec3e63 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java index 1747f7569f..bda3d4cfc1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java index 4780ccf6f4..9741de9895 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java index 54027f1d32..87bba84855 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java index 47e4f2e28c..f903ef16e7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java index a498c25ea4..b6655ab9ff 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java index ab5da2f570..f70bd3c5e5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java index dec3a69f73..59934bce0b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/CriteriaDefinition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/CriteriaDefinition.java index 0829019b8f..e3dfc6da29 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/CriteriaDefinition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/CriteriaDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Query.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Query.java index 57dd5c2846..5e1b630302 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Query.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java index c312b80d20..9b15dd9f23 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/ValueFunction.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/ValueFunction.java index a4ff4f95da..4e81a61075 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/ValueFunction.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/ValueFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractImportValidator.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractImportValidator.java index 1b02e1bea3..1ad5d55de6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractImportValidator.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractImportValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractSegment.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractSegment.java index 76bda66d53..a252230ec2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractSegment.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AbstractSegment.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Aliased.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Aliased.java index 4c163e4eba..5efa2c747e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Aliased.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Aliased.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AliasedExpression.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AliasedExpression.java index 068a109ca3..4a693baa9c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AliasedExpression.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AliasedExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AnalyticFunction.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AnalyticFunction.java index fde47bb70a..407ac4af13 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AnalyticFunction.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AnalyticFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AndCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AndCondition.java index f1a0c0e622..e0e1579ef8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AndCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AndCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java index 21de0676da..3cbc44fcc1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignment.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignment.java index 49acf17aca..3b5709dbd0 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignment.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignment.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignments.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignments.java index e4e6c91cac..8ea21c3f41 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignments.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Assignments.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java index b2af696f39..6066a3d265 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java index ef3f03f81a..8bad4d09fa 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BindMarker.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BindMarker.java index 2a55019686..25bed4c7dd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BindMarker.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BindMarker.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BooleanLiteral.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BooleanLiteral.java index 3d496c47fc..304e5c68c6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BooleanLiteral.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/BooleanLiteral.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Cast.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Cast.java index b0d0941f5e..f020303a17 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Cast.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Cast.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Column.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Column.java index 71f3ab2d5f..a919134965 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Column.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Column.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Comparison.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Comparison.java index 196315c052..a59dc264b7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Comparison.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Comparison.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java index 4287a0af59..ebf3b905db 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Condition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Condition.java index 956d2c6860..c9dbc23de1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Condition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Condition.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Conditions.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Conditions.java index b2f7d894a1..858b16c677 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Conditions.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Conditions.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/ConstantCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/ConstantCondition.java index f8f1baf30c..80d22b815c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/ConstantCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/ConstantCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDelete.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDelete.java index f626b88593..ec128c5ced 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDelete.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDelete.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDeleteBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDeleteBuilder.java index 47474f558f..6890ca23de 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDeleteBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultDeleteBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessing.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessing.java index 6a168fba9e..4fb49ceb74 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessing.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsert.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsert.java index 9e8c73ff8c..f0c4315cdd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsert.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsert.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsertBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsertBuilder.java index 702cc0767b..5e37e29341 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsertBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultInsertBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelect.java index 06f449d78e..ccb1721ff5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelect.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelectBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelectBuilder.java index 8e220d843f..ac2712d7f1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelectBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSelectBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java index c98c164f19..f7b84154b2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdate.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdate.java index 0b4270552a..159c3bcdb4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdate.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdate.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdateBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdateBuilder.java index 9f087aaf57..dd865870c0 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdateBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultUpdateBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Delete.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Delete.java index 1fc10e17f5..e487272f55 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Delete.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Delete.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteBuilder.java index 54826f8e77..147f1fb4ba 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteValidator.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteValidator.java index 30c29e5584..81856606da 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteValidator.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expression.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expression.java index e7042e19d5..755bcd706b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expression.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expression.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expressions.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expressions.java index e6981f8607..c4bc841c65 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expressions.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Expressions.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/FalseCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/FalseCondition.java index dce130c556..cd7864d5dd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/FalseCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/FalseCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/From.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/From.java index e41d6955d2..76cc577239 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/From.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/From.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Functions.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Functions.java index 4b8c23f285..3db8b996a1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Functions.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Functions.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IdentifierProcessing.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IdentifierProcessing.java index 31e85483b8..62099f4b6b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IdentifierProcessing.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IdentifierProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/In.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/In.java index 5524a24247..7f85677bc7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/In.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/In.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InlineQuery.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InlineQuery.java index 02b3354a1d..fd2b3e1849 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InlineQuery.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InlineQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Insert.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Insert.java index 7a50210a24..c3f1c40e73 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Insert.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Insert.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InsertBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InsertBuilder.java index a9278d60ed..de800dcbba 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InsertBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/InsertBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Into.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Into.java index 14218841bd..b105e0ffa0 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Into.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Into.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IsNull.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IsNull.java index 4d46a888e0..71e3412468 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IsNull.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/IsNull.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Join.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Join.java index 8adfea5144..8ef481fb99 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Join.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Join.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java index 826275553b..d3309ff46c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Literal.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Literal.java index a222aa8c27..8e2bf2b838 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Literal.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Literal.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockMode.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockMode.java index 4edd510bef..492e1a59e2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockMode.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockMode.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockOptions.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockOptions.java index 92e1c62ebf..2dd5dee73d 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockOptions.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/LockOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/MultipleCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/MultipleCondition.java index b28f234965..745a63535c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/MultipleCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/MultipleCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Named.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Named.java index 107d023f93..c2884eb5cf 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Named.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Named.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NestedCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NestedCondition.java index e9eb653545..2fc0f7bcb5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NestedCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NestedCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Not.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Not.java index 6b86a7e5a0..556cd601d8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Not.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Not.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NumericLiteral.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NumericLiteral.java index eff1300872..d18fde4c33 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NumericLiteral.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/NumericLiteral.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrCondition.java index 13cc11bddd..2fe3bc3941 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderBy.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderBy.java index e66418ad81..5ebdeffd90 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderBy.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderBy.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java index a98e15956c..a40b364eed 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SQL.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SQL.java index 79c8f556d9..3dd6fc921f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SQL.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SQL.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Segment.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Segment.java index 09cd2cfe0d..ecf29ffbc9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Segment.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Segment.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SegmentList.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SegmentList.java index fb382c5df3..9b384fa738 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SegmentList.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SegmentList.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Select.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Select.java index 73817bbf6b..032068ae03 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Select.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Select.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectBuilder.java index 7364e50ecc..9096d3dd96 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectList.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectList.java index 93225f6fad..73c503aa51 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectList.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectList.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectValidator.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectValidator.java index e95936bddd..7bb827da7e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectValidator.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java index eeadfbda6b..2a8b3f6f86 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleFunction.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleFunction.java index 9c24c5187f..21ec546564 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleFunction.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleSegment.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleSegment.java index 8a3b0e3ebb..4715271e8c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleSegment.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleSegment.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java index b887fa416c..56a88cd995 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StatementBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StatementBuilder.java index f01e23c315..75b37fc088 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StatementBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StatementBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StringLiteral.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StringLiteral.java index 61869fd65e..24d025203f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StringLiteral.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/StringLiteral.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SubselectExpression.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SubselectExpression.java index d2b677ddc2..a5df18daab 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SubselectExpression.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SubselectExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Table.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Table.java index 39b2892847..f775ed1f14 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Table.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Table.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TableLike.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TableLike.java index 46491dbe33..45fe3322aa 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TableLike.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TableLike.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TrueCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TrueCondition.java index 368f991a8b..33053b4e98 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TrueCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/TrueCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Update.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Update.java index 3af1b27a22..5a71163b5a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Update.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Update.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/UpdateBuilder.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/UpdateBuilder.java index 5c944e2373..64413104d6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/UpdateBuilder.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/UpdateBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Values.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Values.java index 23bbef5813..578efd0312 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Values.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Values.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitable.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitable.java index e460e5d3c0..8e93144dd9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitable.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitable.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitor.java index 3b33e3b0bc..334d2b3de4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Visitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java index 240373e8df..d5867eaf20 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AnalyticFunctionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AnalyticFunctionVisitor.java index 33526019a5..629c3210b3 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AnalyticFunctionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AnalyticFunctionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AssignmentVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AssignmentVisitor.java index ce9364fcf2..6f32cdb7fb 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AssignmentVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/AssignmentVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/BetweenVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/BetweenVisitor.java index dd7f5f7913..16209bf96b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/BetweenVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/BetweenVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/CastVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/CastVisitor.java index a89e709931..567e0a057f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/CastVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/CastVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ColumnVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ColumnVisitor.java index 99ff7fed27..67fa70a68d 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ColumnVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ColumnVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ComparisonVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ComparisonVisitor.java index 476f1223b5..849952fb12 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ComparisonVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ComparisonVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConditionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConditionVisitor.java index b6231efa26..9c1327fc1e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConditionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConstantConditionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConstantConditionVisitor.java index 09df0a659a..5dd7992f3c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConstantConditionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ConstantConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DelegatingVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DelegatingVisitor.java index f61b25c1a9..14b8dec04e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DelegatingVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DelegatingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DeleteStatementVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DeleteStatementVisitor.java index ea29c186f0..49a765a4be 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DeleteStatementVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/DeleteStatementVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/EmptyInVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/EmptyInVisitor.java index 3ffab57da6..ed6a42a990 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/EmptyInVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/EmptyInVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ExpressionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ExpressionVisitor.java index 097bf7b16f..3323e01fd8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ExpressionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ExpressionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSingleConditionRenderSupport.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSingleConditionRenderSupport.java index 088290b958..d33d8d93e6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSingleConditionRenderSupport.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSingleConditionRenderSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSubtreeVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSubtreeVisitor.java index 7ea1d95c71..90ad9e1d10 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSubtreeVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSubtreeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromClauseVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromClauseVisitor.java index 1b14e75530..7472abcdd7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromClauseVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromClauseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromTableVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromTableVisitor.java index a8f2e3334b..59298149c7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromTableVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FromTableVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InVisitor.java index f6658e6825..b01f2012a3 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java index 472914c520..66cfbafbb8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/InsertStatementVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IntoClauseVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IntoClauseVisitor.java index 67c814d9d9..a29f309867 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IntoClauseVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IntoClauseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IsNullVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IsNullVisitor.java index c9f2dbcf97..7c04ad496a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IsNullVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/IsNullVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/JoinVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/JoinVisitor.java index 91273258a3..3ca6b72aed 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/JoinVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/JoinVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/LikeVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/LikeVisitor.java index 64c56a3e01..64444190e2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/LikeVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/LikeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/MultiConcatConditionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/MultiConcatConditionVisitor.java index 79270a3d6a..eb6234f026 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/MultiConcatConditionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/MultiConcatConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java index eda5f76488..45c91fa78f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NamingStrategies.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NamingStrategies.java index e0f51ddb50..3e58863f89 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NamingStrategies.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NamingStrategies.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NestedConditionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NestedConditionVisitor.java index 8dc3aa6aa1..ad271f4416 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NestedConditionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NestedConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/PartRenderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/PartRenderer.java index 009553f721..1998459b14 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/PartRenderer.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/PartRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java index 38a1c21035..6cfc47731e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderNamingStrategy.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderNamingStrategy.java index 01f2661066..2d6e45e57f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderNamingStrategy.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderNamingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderTarget.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderTarget.java index b1d7fecfcf..e67dfea66e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderTarget.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/RenderTarget.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/Renderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/Renderer.java index 91f3c7a9d4..dac04ff4b7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/Renderer.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/Renderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SegmentListVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SegmentListVisitor.java index 8f455e2f26..30e4fa9773 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SegmentListVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SegmentListVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectListVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectListVisitor.java index 183515971a..23f5d96677 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectListVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectListVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectStatementVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectStatementVisitor.java index 3b545d3c3b..a098744c84 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectStatementVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SelectStatementVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java index 1f76386936..2c96dbb740 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleFunctionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java index 552067a40e..42dd319c0c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SimpleRenderContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java index 939993468d..8a4dc8d5a5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/SqlRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSingleConditionRenderSupport.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSingleConditionRenderSupport.java index b485cac22f..4f87a8c2f7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSingleConditionRenderSupport.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSingleConditionRenderSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java index 1d64b7edd3..78c23120a5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/UpdateStatementVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/UpdateStatementVisitor.java index b407c1f308..16508e46d4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/UpdateStatementVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/UpdateStatementVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ValuesVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ValuesVisitor.java index f6437a5325..6da21398df 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ValuesVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/ValuesVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/WhereClauseVisitor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/WhereClauseVisitor.java index 85436a2bcc..bd27bc4d4a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/WhereClauseVisitor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/WhereClauseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/CriteriaFactory.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/CriteriaFactory.java index 5a0bc5cdda..08a275e257 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/CriteriaFactory.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/CriteriaFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadata.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadata.java index 252730102e..8683b86070 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadata.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadataProvider.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadataProvider.java index c15733c4dc..bac2c62602 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadataProvider.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/ParameterMetadataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java index 20a9c5f88f..f07e08bb6d 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java index 06d246abeb..6b4c4732e7 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalExampleMapper.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalExampleMapper.java index c242ac43d9..7380572dc7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalExampleMapper.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalExampleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java index 44e4031ff1..5e85d985e0 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java index 78d3d02ece..05da136e67 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java index 046eca11af..1e0151c7f1 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalQueryCreator.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalQueryCreator.java index 1b366419df..161024dd43 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalQueryCreator.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/RelationalQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java index 52d5d1ee39..308ecd7afe 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java index 67f8fbea10..a899c36e1a 100755 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/main/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensions.kt b/spring-data-relational/src/main/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensions.kt index 73a85cf06e..a455434885 100644 --- a/spring-data-relational/src/main/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensions.kt +++ b/spring-data-relational/src/main/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionExecutionExceptionUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionExecutionExceptionUnitTests.java index 0a251bbc66..77476dfb38 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionExecutionExceptionUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionExecutionExceptionUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionTestSupport.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionTestSupport.java index 04245a6d10..0e23382709 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionTestSupport.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/DbActionTestSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java index 02dc1a9de6..42dae35f2f 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java index ab7039723b..1615b32662 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java index a2b3eace91..0c1443e647 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java index 99ee30fef3..d73917d497 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/EscaperUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/EscaperUnitTests.java index 3ff58c79b0..c077855b29 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/EscaperUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/EscaperUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/HsqlDbDialectUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/HsqlDbDialectUnitTests.java index 24bfda3c17..feb3d9400a 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/HsqlDbDialectUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/HsqlDbDialectUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectRenderingUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectRenderingUnitTests.java index d15090f9a1..e06534d785 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectRenderingUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectRenderingUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectUnitTests.java index db1e809d4e..4523279d55 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/MySqlDialectUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectUnitTests.java index ca5f7efc89..397f0e307b 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/PostgresDialectUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectUnitTests.java index bc8a3729dc..0640780d12 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/SqlServerDialectUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverterUnitTests.java index dee5e7befc..37b62eac8e 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/dialect/TimestampAtUtcToOffsetDateTimeConverterUnitTests.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java index d196e49564..7c31ee9313 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentPropertyUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifierUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifierUnitTests.java index 45788a96d9..df63572791 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifierUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifierUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/NamingStrategyUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/NamingStrategyUnitTests.java index dbb9baa3ad..0f1b6ae015 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/NamingStrategyUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/NamingStrategyUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java index 2869671784..0a235fea5b 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImplUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImplUnitTests.java index fd0575e5e9..8008a3c96c 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImplUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImplUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListenerUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListenerUnitTests.java index 3f82924738..c740a909a3 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListenerUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListenerUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java index 6c31a9725d..6529ad7610 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/QueryUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/QueryUnitTests.java index 21467e7725..6c7de09595 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/QueryUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/QueryUnitTests.java @@ -1,5 +1,5 @@ /* -* Copyright 2020-2021 the original author or authors. +* Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/UpdateUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/UpdateUnitTests.java index 5eee96281c..9ef19e3318 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/UpdateUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/UpdateUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractSegmentTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractSegmentTests.java index 85769a8e64..9a6eb89beb 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractSegmentTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractSegmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractTestSegment.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractTestSegment.java index f8a22507ea..2f357d53d5 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractTestSegment.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/AbstractTestSegment.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/CapturingVisitor.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/CapturingVisitor.java index ba94f5ecd3..5f81461602 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/CapturingVisitor.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/CapturingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/ConditionsUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/ConditionsUnitTests.java index e8b875e30a..df8b49784b 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/ConditionsUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/ConditionsUnitTests.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test; /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessingUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessingUnitTests.java index f1b00b4258..a9a92cec6a 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessingUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DefaultIdentifierProcessingUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteBuilderUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteBuilderUnitTests.java index 3d32217dae..e6108b0275 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteBuilderUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteBuilderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteValidatorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteValidatorUnitTests.java index 3342d1572e..153ebbc1a8 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteValidatorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteValidatorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InTests.java index f0bf162956..054f0cf013 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InTests.java @@ -1,5 +1,5 @@ /* -* Copyright 2020-2021 the original author or authors. +* Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InsertBuilderUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InsertBuilderUnitTests.java index f2f3643ef4..6ac8303565 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InsertBuilderUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/InsertBuilderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectBuilderUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectBuilderUnitTests.java index c3e0e73333..ed10402f7d 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectBuilderUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectBuilderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectValidatorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectValidatorUnitTests.java index c09d92f1f6..6d32e2b927 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectValidatorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectValidatorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SqlIdentifierUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SqlIdentifierUnitTests.java index a01bf854ff..b81e751775 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SqlIdentifierUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SqlIdentifierUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestFrom.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestFrom.java index d30547ec49..11d1c19cad 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestFrom.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestFrom.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestJoin.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestJoin.java index ff4cd69194..419c98869b 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestJoin.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/TestJoin.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/UpdateBuilderUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/UpdateBuilderUnitTests.java index 70a4dc64ab..3342f09190 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/UpdateBuilderUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/UpdateBuilderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ConditionRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ConditionRendererUnitTests.java index 3cf7cba04a..f1109a7bc5 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ConditionRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ConditionRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/DeleteRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/DeleteRendererUnitTests.java index ca7a01102f..f117201e12 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/DeleteRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/DeleteRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ExpressionVisitorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ExpressionVisitorUnitTests.java index 96f4351822..2cbdbe92ab 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ExpressionVisitorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/ExpressionVisitorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/FromClauseVisitorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/FromClauseVisitorUnitTests.java index 389b77c11f..3c11f45bba 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/FromClauseVisitorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/FromClauseVisitorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/InsertRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/InsertRendererUnitTests.java index c0fee3d9eb..3105feaf2c 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/InsertRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/InsertRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/JoinVisitorTestsUnitTest.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/JoinVisitorTestsUnitTest.java index bec6b8f8db..8473761bec 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/JoinVisitorTestsUnitTest.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/JoinVisitorTestsUnitTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/NameRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/NameRendererUnitTests.java index af103b15ff..74475808a1 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/NameRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/NameRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitorUnitTests.java index e77700280d..45dff676fe 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/OrderByClauseVisitorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/SelectRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/SelectRendererUnitTests.java index 093c251360..8119d55780 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/SelectRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/SelectRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitorUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitorUnitTests.java index 45beeb95c9..95a11ac539 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitorUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitorUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/UpdateRendererUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/UpdateRendererUnitTests.java index 5675050f16..6511140d01 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/UpdateRendererUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/render/UpdateRendererUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/degraph/DependencyTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/degraph/DependencyTests.java index 2e074de07e..2040bc2d4a 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/degraph/DependencyTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/degraph/DependencyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/CriteriaFactoryUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/CriteriaFactoryUnitTests.java index c6b36fa464..8f0833d3c0 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/CriteriaFactoryUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/CriteriaFactoryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/ParameterMetadataProviderUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/ParameterMetadataProviderUnitTests.java index 4e1abe3c25..fdbee3d731 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/ParameterMetadataProviderUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/ParameterMetadataProviderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/RelationalExampleMapperTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/RelationalExampleMapperTests.java index 3b080ed11e..b981004f70 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/RelationalExampleMapperTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/repository/query/RelationalExampleMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-data-relational/src/test/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensionsTests.kt b/spring-data-relational/src/test/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensionsTests.kt index b965a14d22..dae6e9a0f9 100644 --- a/spring-data-relational/src/test/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensionsTests.kt +++ b/spring-data-relational/src/test/kotlin/org/springframework/data/relational/core/query/CriteriaStepExtensionsTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 6839f77fd2..abde3d3faf 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -7,7 +7,7 @@ ifdef::backend-epub3[:front-cover-image: image:epub-cover.png[Front Cover,1050,1 :spring-data-commons-docs: ../../../../../spring-data-commons/src/main/asciidoc :spring-framework-docs: https://docs.spring.io/spring-framework/docs/{springVersion}/reference/html -(C) 2018-2021 The original authors. +(C) 2018-2022 The original authors. NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. From 2937cd08d979a9474a7b4e6eaeebfce54127451d Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 18 Feb 2022 11:08:46 +0100 Subject: [PATCH 28/51] Prepare 2.4 M3 (2021.2.0). See #1133 --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 2c64717780..217f4642ee 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-SNAPSHOT + 2.7.0-M3 spring-data-jdbc - 2.7.0-SNAPSHOT + 2.7.0-M3 reuseReports @@ -276,8 +276,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index c3d360e056..0e36d5f5a7 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data JDBC 2.4 M2 (2021.2.0) +Spring Data JDBC 2.4 M3 (2021.2.0) Copyright (c) [2017-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -32,5 +32,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From cd84c8d551607dde98b7586e84b9258de9df2586 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 18 Feb 2022 11:09:10 +0100 Subject: [PATCH 29/51] Release version 2.4 M3 (2021.2.0). See #1133 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 217f4642ee..da581fe647 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M3 pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 0646c2846d..f4080746ce 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M3 ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 11114a795e..b6b52cd32a 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-SNAPSHOT + 2.4.0-M3 Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M3 diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index a6eb48c891..03a1259690 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-SNAPSHOT + 2.4.0-M3 Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-SNAPSHOT + 2.4.0-M3 From b36e8092e11e0d9bb373b72c4ea8a8dccbf8a2b8 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 18 Feb 2022 11:15:39 +0100 Subject: [PATCH 30/51] Prepare next development iteration. See #1133 --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index da581fe647..217f4642ee 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M3 + 2.4.0-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index f4080746ce..0646c2846d 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M3 + 2.4.0-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index b6b52cd32a..11114a795e 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.4.0-M3 + 2.4.0-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M3 + 2.4.0-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 03a1259690..a6eb48c891 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.4.0-M3 + 2.4.0-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.4.0-M3 + 2.4.0-SNAPSHOT From 0240b64adad1b0c2ec5d80986152c5481f70efca Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 18 Feb 2022 11:15:41 +0100 Subject: [PATCH 31/51] After release cleanups. See #1133 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 217f4642ee..2c64717780 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ org.springframework.data.build spring-data-parent - 2.7.0-M3 + 2.7.0-SNAPSHOT spring-data-jdbc - 2.7.0-M3 + 2.7.0-SNAPSHOT reuseReports @@ -276,8 +276,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From b7afc380e12d7923411a17e1d183bf64257015ac Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Thu, 17 Feb 2022 16:26:06 +0100 Subject: [PATCH 32/51] `StringBuilder` can be replaced with String concatenation. In this case the usage of `StringBuilder` has no additional benefit, since it is not inside a loop where the JVM may have problems detecting String concatenation that can be optimized. The usage of "simple" String concatenation makes the code more readable and the code will be automatically optimised by the compiler. Original pull request #1173 --- .../springframework/data/relational/core/sql/AssignValue.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java index 3cbc44fcc1..5bd222592b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AssignValue.java @@ -72,7 +72,6 @@ public Expression getValue() { @Override public String toString() { - StringBuilder builder = new StringBuilder(); - return builder.append(this.column).append(" = ").append(this.value).toString(); + return this.column + " = " + this.value; } } From 9554fdfe480eda109926aaf46b6160c3da355582 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Thu, 17 Feb 2022 16:03:17 +0100 Subject: [PATCH 33/51] Remove unnecessary `toString()` call. There were few explicit `toString()` calls that are not needed, since `toString()` will be called by default. Original pull request #1172 --- .../org/springframework/data/relational/core/query/Update.java | 2 +- .../data/relational/core/sql/AsteriskFromTable.java | 2 +- .../org/springframework/data/relational/core/sql/Between.java | 2 +- .../java/org/springframework/data/relational/core/sql/Like.java | 2 +- .../springframework/data/relational/core/sql/OrderByField.java | 2 +- .../data/relational/core/sql/SimpleCondition.java | 2 +- .../org/springframework/data/relational/core/sql/Where.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java index 9b15dd9f23..e5b76b7c38 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java @@ -122,6 +122,6 @@ public String toString() { String.format("%s = %s", column.toSql(IdentifierProcessing.NONE), o instanceof Number ? o : "'" + o + "'")); }); - return "SET " + joiner.toString(); + return "SET " + joiner; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java index 6066a3d265..32933c5736 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/AsteriskFromTable.java @@ -55,6 +55,6 @@ public String toString() { return ((Aliased) table).getAlias() + ".*"; } - return table.toString() + ".*"; + return table + ".*"; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java index 8bad4d09fa..a6cd1eb95b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java @@ -91,6 +91,6 @@ public Between not() { @Override public String toString() { - return column.toString() + " BETWEEN " + begin.toString() + " AND " + end.toString(); + return column + " BETWEEN " + begin + " AND " + end; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java index d3309ff46c..aeccda54d9 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java @@ -80,6 +80,6 @@ public Like not() { @Override public String toString() { - return left.toString() + " LIKE " + right.toString(); + return left + " LIKE " + right; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java index a40b364eed..7608e081fa 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java @@ -115,6 +115,6 @@ public NullHandling getNullHandling() { */ @Override public String toString() { - return direction != null ? expression.toString() + " " + direction : expression.toString(); + return direction != null ? expression + " " + direction : expression.toString(); } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java index 2a8b3f6f86..8a916168f3 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SimpleCondition.java @@ -75,6 +75,6 @@ public String getPredicate() { */ @Override public String toString() { - return expression.toString() + " " + comparator + " " + predicate; + return expression + " " + comparator + " " + predicate; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java index d5867eaf20..0ac054e7ff 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Where.java @@ -38,6 +38,6 @@ public class Where extends AbstractSegment { */ @Override public String toString() { - return "WHERE " + condition.toString(); + return "WHERE " + condition; } } From 63f233172794e14fbe53b3f0b6485a130721b694 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 21 Feb 2022 14:54:22 +0100 Subject: [PATCH 34/51] Avoid conversion when return value is null. Closes #1167 --- .../repository/query/AbstractJdbcQuery.java | 2 +- .../JdbcRepositoryIntegrationTests.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java index 2d7df924ed..f9f2b2e484 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java @@ -184,7 +184,7 @@ public Object mapRow(ResultSet rs, int rowNum) throws SQLException { T object = delegate.mapRow(rs, rowNum); - return converter.convert(object); + return object == null ? null : converter.convert(object); } } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 048a78a5dc..cfaa6df57c 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -37,7 +37,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.ApplicationListener; @@ -70,6 +69,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.lang.Nullable; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.jdbc.JdbcTestUtils; @@ -559,6 +559,22 @@ void queryByAggregateReference() { assertThat(result).extracting(e -> e.idProp).containsExactly(two.idProp); } + @Test // GH-1167 + void stringResult() { + + repository.save(createDummyEntity()); // just ensure we have data in the table + + assertThat(repository.returnInput("HELLO")).isEqualTo("HELLO"); + } + + @Test // GH-1167 + void nullStringResult() { + + repository.save(createDummyEntity()); // just ensure we have data in the table + + assertThat(repository.returnInput(null)).isNull(); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); @@ -640,6 +656,10 @@ interface DummyEntityRepository extends CrudRepository { List findByRef(int ref); List findByRef(AggregateReference ref); + + @Query("SELECT CAST(:hello AS CHAR(5)) FROM DUMMY_ENTITY") + @Nullable + String returnInput(@Nullable String hello); } @Configuration From aa8c8a1743f6093c9f004dd49516435e20d7c38e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 22 Feb 2022 09:06:49 +0100 Subject: [PATCH 35/51] Use Java 17 to build snapshots for Artifactory. Closes #1180 --- Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a20fac4340..9b00591f9d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -74,7 +74,7 @@ pipeline { docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" - sh "PROFILE=ci,java11 ci/test.sh" + sh "PROFILE=ci ci/test.sh" sh "ci/clean.sh" } } @@ -98,7 +98,7 @@ pipeline { docker.withRegistry(p['docker.registry'], p['docker.credentials']) { docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.docker']) { sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" - sh "PROFILE=ci,java11 ci/test.sh" + sh "PROFILE=ci ci/test.sh" sh "ci/clean.sh" } } @@ -128,7 +128,7 @@ pipeline { steps { script { docker.withRegistry(p['docker.registry'], p['docker.credentials']) { - docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) { + docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.basic']) { sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-jdbc-non-root ' + '-Dartifactory.server=https://repo.spring.io ' + "-Dartifactory.username=${ARTIFACTORY_USR} " + From 23983bb3b53ee58e53a384e712da19975d005a0b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 22 Feb 2022 13:59:08 +0100 Subject: [PATCH 36/51] Upgrade to Maven Wrapper 3.8.4. See #1184 --- .mvn/wrapper/maven-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 84fe0f8868..4af182c4df 100755 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -#Mon Oct 11 14:30:22 CEST 2021 -distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip +#Tue Feb 22 13:59:08 CET 2022 +distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip From 98d2b223d3f56f1a1c39ae75bd93b851429d9559 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 22 Feb 2022 14:09:31 +0100 Subject: [PATCH 37/51] Update CI properties. See #1176 --- ci/pipeline.properties | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ci/pipeline.properties b/ci/pipeline.properties index b3314cdc63..f3c84e0527 100644 --- a/ci/pipeline.properties +++ b/ci/pipeline.properties @@ -1,7 +1,7 @@ # Java versions -java.main.tag=8u312-b07-jdk -java.next.tag=11.0.13_8-jdk -java.lts.tag=17.0.1_12-jdk +java.main.tag=8u322-b06-jdk +java.next.tag=11.0.14.1_1-jdk +java.lts.tag=17.0.2_8-jdk # Docker container images - standard docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag} @@ -9,15 +9,15 @@ docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/ecli docker.java.lts.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.lts.tag} # Supported versions of MongoDB -docker.mongodb.4.0.version=4.0.23 -docker.mongodb.4.4.version=4.4.4 -docker.mongodb.5.0.version=5.0.3 +docker.mongodb.4.0.version=4.0.28 +docker.mongodb.4.4.version=4.4.12 +docker.mongodb.5.0.version=5.0.6 # Supported versions of Redis -docker.redis.6.version=6.2.4 +docker.redis.6.version=6.2.6 # Supported versions of Cassandra -docker.cassandra.3.version=3.11.10 +docker.cassandra.3.version=3.11.12 # Docker environment settings docker.java.inside.basic=-v $HOME:/tmp/jenkins-home From c8eafe733707f8eae309e4cbdad02adb08bcdf13 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 22 Feb 2022 15:45:51 +0100 Subject: [PATCH 38/51] Move Lock to relational module. This allows both Spring Data R2DBC and Spring Data JDBC to use the same annotation. See spring-projects/spring-data-jdbc/issues/1041, spring-projects/spring-data-r2dbc/pull/720, spring-projects/spring-data-jdbc/pull/1158 --- .../data/jdbc/repository/query/JdbcCountQueryCreator.java | 1 + .../data/jdbc/repository/query/JdbcQueryCreator.java | 1 + .../data/jdbc/repository/query/JdbcQueryMethod.java | 1 + .../data/jdbc/repository/JdbcRepositoryIntegrationTests.java | 2 +- .../data/jdbc/repository/query/JdbcQueryMethodUnitTests.java | 1 + .../data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java | 2 +- .../org/springframework/data/relational/repository}/Lock.java | 2 +- 7 files changed, 7 insertions(+), 3 deletions(-) rename {spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query => spring-data-relational/src/main/java/org/springframework/data/relational/repository}/Lock.java (95%) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java index 58c9158839..25a5cf7c9a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcCountQueryCreator.java @@ -25,6 +25,7 @@ import org.springframework.data.relational.core.sql.Select; import org.springframework.data.relational.core.sql.SelectBuilder; import org.springframework.data.relational.core.sql.Table; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.relational.repository.query.RelationalEntityMetadata; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; import org.springframework.data.repository.query.ReturnedType; diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java index e21248ca5d..78d82547f0 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java @@ -41,6 +41,7 @@ import org.springframework.data.relational.core.sql.StatementBuilder; import org.springframework.data.relational.core.sql.Table; import org.springframework.data.relational.core.sql.render.SqlRenderer; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.relational.repository.query.RelationalEntityMetadata; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; import org.springframework.data.relational.repository.query.RelationalQueryCreator; diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java index 9c979bcce9..170c4615ca 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java @@ -26,6 +26,7 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.relational.repository.query.RelationalEntityMetadata; import org.springframework.data.relational.repository.query.RelationalParameters; import org.springframework.data.relational.repository.query.SimpleRelationalEntityMetadata; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index cfaa6df57c..85f9e1e1f7 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -50,7 +50,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jdbc.core.mapping.AggregateReference; -import org.springframework.data.jdbc.repository.query.Lock; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java index a707f854a4..8c7a4725e2 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethodUnitTests.java @@ -28,6 +28,7 @@ import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java index eded809c00..e888226a34 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java @@ -42,8 +42,8 @@ import org.springframework.data.relational.core.mapping.Embedded; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; -import org.springframework.data.relational.core.sql.In; import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.Repository; diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/Lock.java similarity index 95% rename from spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java rename to spring-data-relational/src/main/java/org/springframework/data/relational/repository/Lock.java index 1fd310b85f..6df55a6521 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Lock.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/repository/Lock.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jdbc.repository.query; +package org.springframework.data.relational.repository; import org.springframework.data.annotation.QueryAnnotation; import org.springframework.data.relational.core.sql.LockMode; From 5352fe34cf15e375d84307301dd035f3f54f4bd5 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 28 Feb 2022 15:17:44 +0100 Subject: [PATCH 39/51] Associate value with isTrue/isFalse criteria operators. We now associate a boolean value with both operators as those operators are rendered using equals comparison in the actual SQL text. Orginal pull request #1188 --- .../data/jdbc/repository/query/QueryMapper.java | 6 ++++-- .../data/relational/core/query/Criteria.java | 4 ++-- .../data/relational/core/query/CriteriaUnitTests.java | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java index 33a3a4fad9..d674417d37 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java @@ -494,13 +494,15 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, S if (comparator == Comparator.IS_TRUE) { - Expression bind = bindBoolean(column, parameterSource, true); + Expression bind = bindBoolean(column, parameterSource, + mappedValue instanceof Boolean ? (Boolean) mappedValue : true); return column.isEqualTo(bind); } if (comparator == Comparator.IS_FALSE) { - Expression bind = bindBoolean(column, parameterSource, false); + Expression bind = bindBoolean(column, parameterSource, + mappedValue instanceof Boolean ? (Boolean) mappedValue : false); return column.isEqualTo(bind); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java index 59934bce0b..a4485b8664 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java @@ -849,7 +849,7 @@ public Criteria isNotNull() { */ @Override public Criteria isTrue() { - return createCriteria(Comparator.IS_TRUE, null); + return createCriteria(Comparator.IS_TRUE, true); } /* @@ -858,7 +858,7 @@ public Criteria isTrue() { */ @Override public Criteria isFalse() { - return createCriteria(Comparator.IS_FALSE, null); + return createCriteria(Comparator.IS_FALSE, false); } protected Criteria createCriteria(Comparator comparator, @Nullable Object value) { diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java index 6529ad7610..02439f851d 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java @@ -285,6 +285,7 @@ public void shouldBuildIsTrueCriteria() { assertThat(criteria.getColumn()).isEqualTo(SqlIdentifier.unquoted("foo")); assertThat(criteria.getComparator()).isEqualTo(CriteriaDefinition.Comparator.IS_TRUE); + assertThat(criteria.getValue()).isEqualTo(true); } @Test // DATAJDBC-513 @@ -294,5 +295,6 @@ public void shouldBuildIsFalseCriteria() { assertThat(criteria.getColumn()).isEqualTo(SqlIdentifier.unquoted("foo")); assertThat(criteria.getComparator()).isEqualTo(CriteriaDefinition.Comparator.IS_FALSE); + assertThat(criteria.getValue()).isEqualTo(false); } } From bd0be7713734faaf526c341b4059242d176e5bf5 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 28 Feb 2022 15:18:01 +0100 Subject: [PATCH 40/51] Polishing. Reduce test method visibility. Orginal pull request #1188 --- .../core/query/CriteriaUnitTests.java | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java index 02439f851d..fa05131edc 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/CriteriaUnitTests.java @@ -32,10 +32,10 @@ * @author Jens Schauder * @author Roman Chigvintsev */ -public class CriteriaUnitTests { +class CriteriaUnitTests { @Test // DATAJDBC-513 - public void fromCriteria() { + void fromCriteria() { Criteria nested1 = where("foo").isNotNull(); Criteria nested2 = where("foo").isNull(); @@ -48,7 +48,7 @@ public void fromCriteria() { } @Test // DATAJDBC-513 - public void fromCriteriaOptimized() { + void fromCriteriaOptimized() { Criteria nested = where("foo").is("bar").and("baz").isNotNull(); CriteriaDefinition criteria = Criteria.from(nested); @@ -57,7 +57,7 @@ public void fromCriteriaOptimized() { } @Test // DATAJDBC-513 - public void isEmpty() { + void isEmpty() { assertSoftly(softly -> { @@ -79,7 +79,7 @@ public void isEmpty() { } @Test // DATAJDBC-513 - public void andChainedCriteria() { + void andChainedCriteria() { Criteria criteria = where("foo").is("bar").and("baz").isNotNull(); @@ -97,7 +97,7 @@ public void andChainedCriteria() { } @Test // DATAJDBC-513 - public void andGroupedCriteria() { + void andGroupedCriteria() { Criteria grouped = where("foo").is("bar").and(where("foo").is("baz").or("bar").isNotNull()); Criteria criteria = grouped; @@ -118,7 +118,7 @@ public void andGroupedCriteria() { } @Test // DATAJDBC-513 - public void orChainedCriteria() { + void orChainedCriteria() { Criteria criteria = where("foo").is("bar").or("baz").isNotNull(); @@ -133,7 +133,7 @@ public void orChainedCriteria() { } @Test // DATAJDBC-513 - public void orGroupedCriteria() { + void orGroupedCriteria() { Criteria criteria = where("foo").is("bar").or(where("foo").is("baz")); @@ -151,7 +151,7 @@ public void orGroupedCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildEqualsCriteria() { + void shouldBuildEqualsCriteria() { Criteria criteria = where("foo").is("bar"); @@ -161,7 +161,7 @@ public void shouldBuildEqualsCriteria() { } @Test - public void shouldBuildEqualsIgnoreCaseCriteria() { + void shouldBuildEqualsIgnoreCaseCriteria() { Criteria criteria = where("foo").is("bar").ignoreCase(true); assertThat(criteria.getColumn()).isEqualTo(SqlIdentifier.unquoted("foo")); @@ -171,7 +171,7 @@ public void shouldBuildEqualsIgnoreCaseCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildNotEqualsCriteria() { + void shouldBuildNotEqualsCriteria() { Criteria criteria = where("foo").not("bar"); @@ -181,7 +181,7 @@ public void shouldBuildNotEqualsCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildInCriteria() { + void shouldBuildInCriteria() { Criteria criteria = where("foo").in("bar", "baz"); @@ -192,7 +192,7 @@ public void shouldBuildInCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildNotInCriteria() { + void shouldBuildNotInCriteria() { Criteria criteria = where("foo").notIn("bar", "baz"); @@ -202,7 +202,7 @@ public void shouldBuildNotInCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildGtCriteria() { + void shouldBuildGtCriteria() { Criteria criteria = where("foo").greaterThan(1); @@ -212,7 +212,7 @@ public void shouldBuildGtCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildGteCriteria() { + void shouldBuildGteCriteria() { Criteria criteria = where("foo").greaterThanOrEquals(1); @@ -222,7 +222,7 @@ public void shouldBuildGteCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildLtCriteria() { + void shouldBuildLtCriteria() { Criteria criteria = where("foo").lessThan(1); @@ -232,7 +232,7 @@ public void shouldBuildLtCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildLteCriteria() { + void shouldBuildLteCriteria() { Criteria criteria = where("foo").lessThanOrEquals(1); @@ -242,7 +242,7 @@ public void shouldBuildLteCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildLikeCriteria() { + void shouldBuildLikeCriteria() { Criteria criteria = where("foo").like("hello%"); @@ -252,7 +252,7 @@ public void shouldBuildLikeCriteria() { } @Test - public void shouldBuildNotLikeCriteria() { + void shouldBuildNotLikeCriteria() { Criteria criteria = where("foo").notLike("hello%"); assertThat(criteria.getColumn()).isEqualTo(SqlIdentifier.unquoted("foo")); @@ -261,7 +261,7 @@ public void shouldBuildNotLikeCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildIsNullCriteria() { + void shouldBuildIsNullCriteria() { Criteria criteria = where("foo").isNull(); @@ -270,7 +270,7 @@ public void shouldBuildIsNullCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildIsNotNullCriteria() { + void shouldBuildIsNotNullCriteria() { Criteria criteria = where("foo").isNotNull(); @@ -279,7 +279,7 @@ public void shouldBuildIsNotNullCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildIsTrueCriteria() { + void shouldBuildIsTrueCriteria() { Criteria criteria = where("foo").isTrue(); @@ -289,7 +289,7 @@ public void shouldBuildIsTrueCriteria() { } @Test // DATAJDBC-513 - public void shouldBuildIsFalseCriteria() { + void shouldBuildIsFalseCriteria() { Criteria criteria = where("foo").isFalse(); From 36827110aec49e931d14b73606933d26484fb624 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Thu, 24 Feb 2022 12:46:28 +0100 Subject: [PATCH 41/51] Introduced `queryLookupStrategy` to `EnableJdbcRepositories`. Added the missing functionality that is found in the documentation of spring-data-jdbc, but was not present in the code as functionality. Users can not choose between various QueryLookupStrategies. Closes #1043 Original pull request #1187 --- .../config/EnableJdbcRepositories.java | 13 +- .../support/JdbcQueryLookupStrategy.java | 213 ++++++++++++++++-- .../support/JdbcRepositoryFactory.java | 5 +- ...ositoryLookUpStrategyIntegrationTests.java | 91 ++++++++ ...otFoundLookUpStrategyIntegrationTests.java | 79 +++++++ ...yCreateLookUpStrategyIntegrationTests.java | 76 +++++++ ...eclaredLookUpStrategyIntegrationTests.java | 60 +++++ .../JdbcQueryLookupStrategyUnitTests.java | 59 ++++- ...toryLookUpStrategyIntegrationTests-db2.sql | 7 + ...itoryLookUpStrategyIntegrationTests-h2.sql | 5 + ...oryLookUpStrategyIntegrationTests-hsql.sql | 5 + ...LookUpStrategyIntegrationTests-mariadb.sql | 5 + ...ryLookUpStrategyIntegrationTests-mssql.sql | 7 + ...ryLookUpStrategyIntegrationTests-mysql.sql | 5 + ...yLookUpStrategyIntegrationTests-oracle.sql | 7 + ...ookUpStrategyIntegrationTests-postgres.sql | 6 + 16 files changed, 609 insertions(+), 34 deletions(-) create mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java create mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java create mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java create mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql create mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java index dd60dd7dd6..c5e1694508 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,8 +27,8 @@ import org.springframework.context.annotation.Import; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean; import org.springframework.data.repository.config.DefaultRepositoryBaseClass; +import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; /** * Annotation to enable JDBC repositories. Will scan the package of the annotated configuration class for Spring Data @@ -39,6 +39,7 @@ * @author Mark Paluch * @author Fei Dong * @author Antoine Sauray + * @author Diego Krupitza * @see AbstractJdbcConfiguration */ @Target(ElementType.TYPE) @@ -124,11 +125,17 @@ */ String dataAccessStrategyRef() default ""; - /** + /** * Configures the name of the {@link DataSourceTransactionManager} bean definition to be used to create repositories * discovered through this annotation. Defaults to {@code transactionManager}. + * * @since 2.1 */ String transactionManagerRef() default "transactionManager"; + /** + * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to + * {@link QueryLookupStrategy.Key#CREATE_IF_NOT_FOUND}. + */ + QueryLookupStrategy.Key queryLookupStrategy() default QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java index ab2fc67dd1..4fbdd69f86 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.beans.factory.BeanFactory; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.jdbc.core.convert.EntityRowMapper; @@ -41,7 +40,6 @@ import org.springframework.data.relational.core.mapping.event.AfterLoadEvent; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.QueryCreationException; import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.jdbc.core.RowMapper; @@ -51,7 +49,7 @@ import org.springframework.util.Assert; /** - * {@link QueryLookupStrategy} for JDBC repositories. + * Abstract {@link QueryLookupStrategy} for JDBC repositories. * * @author Jens Schauder * @author Kazuki Shimizu @@ -60,8 +58,9 @@ * @author Maciej Walkowiak * @author Moises Cisneros * @author Hebert Coelho + * @author Diego Krupitza */ -class JdbcQueryLookupStrategy implements QueryLookupStrategy { +abstract class JdbcQueryLookupStrategy implements QueryLookupStrategy { private static final Log LOG = LogFactory.getLog(JdbcQueryLookupStrategy.class); @@ -72,12 +71,12 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy { private final Dialect dialect; private final QueryMappingConfiguration queryMappingConfiguration; private final NamedParameterJdbcOperations operations; - private final BeanFactory beanfactory; + @Nullable private final BeanFactory beanfactory; JdbcQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, RelationalMappingContext context, JdbcConverter converter, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, - BeanFactory beanfactory) { + @Nullable BeanFactory beanfactory) { Assert.notNull(publisher, "ApplicationEventPublisher must not be null"); Assert.notNull(context, "RelationalMappingContextPublisher must not be null"); @@ -96,18 +95,52 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy { this.beanfactory = beanfactory; } - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.projection.ProjectionFactory, org.springframework.data.repository.core.NamedQueries) + /** + * {@link QueryLookupStrategy} to create a query from the method name. + * + * @author Diego Krupitza */ - @Override - public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata, - ProjectionFactory projectionFactory, NamedQueries namedQueries) { + static class CreateQueryLookupStrategy extends JdbcQueryLookupStrategy { + + CreateQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, + RelationalMappingContext context, JdbcConverter converter, Dialect dialect, + QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, + @Nullable BeanFactory beanfactory) { + super(publisher, callbacks, context, converter, dialect, queryMappingConfiguration, operations, beanfactory); + } + + @Override + public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata, + ProjectionFactory projectionFactory, NamedQueries namedQueries) { + + JdbcQueryMethod queryMethod = getJdbcQueryMethod(method, repositoryMetadata, projectionFactory, namedQueries); + + return new PartTreeJdbcQuery(getContext(), queryMethod, getDialect(), getConverter(), getOperations(), + this::createMapper); + } + } + + /** + * {@link QueryLookupStrategy} that tries to detect a declared query declared via + * {@link org.springframework.data.jdbc.repository.query.Query} annotation followed by a JPA named query lookup. + * + * @author Diego Krupitza + */ + static class DeclaredQueryLookupStrategy extends JdbcQueryLookupStrategy { + + DeclaredQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, + RelationalMappingContext context, JdbcConverter converter, Dialect dialect, + QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, + @Nullable BeanFactory beanfactory) { + super(publisher, callbacks, context, converter, dialect, queryMappingConfiguration, operations, beanfactory); + } + + @Override + public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata, + ProjectionFactory projectionFactory, NamedQueries namedQueries) { - JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory, namedQueries, - context); + JdbcQueryMethod queryMethod = getJdbcQueryMethod(method, repositoryMetadata, projectionFactory, namedQueries); - try { if (namedQueries.hasQuery(queryMethod.getNamedQueryName()) || queryMethod.hasAnnotatedQuery()) { if (queryMethod.hasAnnotatedQuery() && queryMethod.hasAnnotatedQueryName()) { @@ -115,24 +148,156 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repository "Query method %s is annotated with both, a query and a query name. Using the declared query.", method)); } - StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, this::createMapper, converter); - query.setBeanFactory(beanfactory); + StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, getOperations(), this::createMapper, + getConverter()); + query.setBeanFactory(getBeanfactory()); return query; - } else { - return new PartTreeJdbcQuery(context, queryMethod, dialect, converter, operations, this::createMapper); } - } catch (Exception e) { - throw QueryCreationException.create(queryMethod, e); + + throw new IllegalStateException( + String.format("Did neither find a NamedQuery nor an annotated query for method %s!", method)); + } + } + + /** + * {@link QueryLookupStrategy} to try to detect a declared query first ( + * {@link org.springframework.data.jdbc.repository.query.Query}, JDBC named query). In case none is found we fall back + * on query creation. + *

+ * Modified based on original source: {@link org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy} + * + * @author Oliver Gierke + * @author Thomas Darimont + * @author Diego Krupitza + */ + static class CreateIfNotFoundQueryLookupStrategy extends JdbcQueryLookupStrategy { + + private final DeclaredQueryLookupStrategy lookupStrategy; + private final CreateQueryLookupStrategy createStrategy; + + /** + * Creates a new {@link CreateIfNotFoundQueryLookupStrategy}. + * + * @param createStrategy must not be {@literal null}. + * @param lookupStrategy must not be {@literal null}. + */ + public CreateIfNotFoundQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, + RelationalMappingContext context, JdbcConverter converter, Dialect dialect, + QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, + @Nullable BeanFactory beanfactory, CreateQueryLookupStrategy createStrategy, + DeclaredQueryLookupStrategy lookupStrategy) { + + super(publisher, callbacks, context, converter, dialect, queryMappingConfiguration, operations, beanfactory); + + Assert.notNull(createStrategy, "CreateQueryLookupStrategy must not be null!"); + Assert.notNull(lookupStrategy, "DeclaredQueryLookupStrategy must not be null!"); + + this.createStrategy = createStrategy; + this.lookupStrategy = lookupStrategy; } + + @Override + public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata, + ProjectionFactory projectionFactory, NamedQueries namedQueries) { + + try { + return lookupStrategy.resolveQuery(method, repositoryMetadata, projectionFactory, namedQueries); + } catch (IllegalStateException e) { + return createStrategy.resolveQuery(method, repositoryMetadata, projectionFactory, namedQueries); + } + } + } + + /** + * Creates a {@link JdbcQueryMethod} based on the parameters + */ + JdbcQueryMethod getJdbcQueryMethod(Method method, RepositoryMetadata repositoryMetadata, + ProjectionFactory projectionFactory, NamedQueries namedQueries) { + return new JdbcQueryMethod(method, repositoryMetadata, projectionFactory, namedQueries, context); + } + + /** + * Creates a {@link QueryLookupStrategy} based on the provided + * {@link org.springframework.data.repository.query.QueryLookupStrategy.Key}. + * + * @param key the key that decides what {@link QueryLookupStrategy} shozld be used. + * @param publisher must not be {@literal null} + * @param callbacks may be {@literal null} + * @param context must not be {@literal null} + * @param converter must not be {@literal null} + * @param dialect must not be {@literal null} + * @param queryMappingConfiguration must not be {@literal null} + * @param operations must not be {@literal null} + * @param beanfactory may be {@literal null} + */ + public static QueryLookupStrategy create(@Nullable Key key, ApplicationEventPublisher publisher, + @Nullable EntityCallbacks callbacks, RelationalMappingContext context, JdbcConverter converter, Dialect dialect, + QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, + @Nullable BeanFactory beanfactory) { + + Assert.notNull(publisher, "ApplicationEventPublisher must not be null"); + Assert.notNull(context, "RelationalMappingContextPublisher must not be null"); + Assert.notNull(converter, "JdbcConverter must not be null"); + Assert.notNull(dialect, "Dialect must not be null"); + Assert.notNull(queryMappingConfiguration, "QueryMappingConfiguration must not be null"); + Assert.notNull(operations, "NamedParameterJdbcOperations must not be null"); + + CreateQueryLookupStrategy createQueryLookupStrategy = new CreateQueryLookupStrategy(publisher, callbacks, context, + converter, dialect, queryMappingConfiguration, operations, beanfactory); + + DeclaredQueryLookupStrategy declaredQueryLookupStrategy = new DeclaredQueryLookupStrategy(publisher, callbacks, + context, converter, dialect, queryMappingConfiguration, operations, beanfactory); + + Key cleanedKey = key != null ? key : Key.CREATE_IF_NOT_FOUND; + + LOG.debug(String.format("Using the queryLookupStrategy %s", cleanedKey)); + + switch (cleanedKey) { + case CREATE: + return createQueryLookupStrategy; + case USE_DECLARED_QUERY: + return declaredQueryLookupStrategy; + case CREATE_IF_NOT_FOUND: + return new CreateIfNotFoundQueryLookupStrategy(publisher, callbacks, context, converter, dialect, + queryMappingConfiguration, operations, beanfactory, createQueryLookupStrategy, declaredQueryLookupStrategy); + default: + throw new IllegalArgumentException(String.format("Unsupported query lookup strategy %s!", key)); + } + } + + protected ApplicationEventPublisher getPublisher() { + return publisher; + } + + protected RelationalMappingContext getContext() { + return context; + } + + protected JdbcConverter getConverter() { + return converter; + } + + protected Dialect getDialect() { + return dialect; + } + + protected NamedParameterJdbcOperations getOperations() { + return operations; + } + + @Nullable + protected BeanFactory getBeanfactory() { + return beanfactory; } @SuppressWarnings("unchecked") - private RowMapper createMapper(Class returnedObjectType) { + RowMapper createMapper(Class returnedObjectType) { RelationalPersistentEntity persistentEntity = context.getPersistentEntity(returnedObjectType); if (persistentEntity == null) { - return (RowMapper) SingleColumnRowMapper.newInstance(returnedObjectType, converter.getConversionService()); + return (RowMapper) SingleColumnRowMapper.newInstance(returnedObjectType, + converter.getConversionService()); } return (RowMapper) determineDefaultMapper(returnedObjectType); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java index 36558f64ba..f3d1f61fb3 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ * @author Christoph Strobl * @author Mark Paluch * @author Hebert Coelho + * @author Diego Krupitza */ public class JdbcRepositoryFactory extends RepositoryFactorySupport { @@ -145,7 +146,7 @@ protected Class getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) protected Optional getQueryLookupStrategy(@Nullable QueryLookupStrategy.Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { - return Optional.of(new JdbcQueryLookupStrategy(publisher, entityCallbacks, context, converter, dialect, + return Optional.of(JdbcQueryLookupStrategy.create(key, publisher, entityCallbacks, context, converter, dialect, queryMappingConfiguration, operations, beanFactory)); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java new file mode 100644 index 0000000000..41e5646c98 --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository; + +import static org.assertj.core.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.annotation.Id; +import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.relational.core.mapping.RelationalMappingContext; +import org.springframework.data.repository.CrudRepository; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +/** + * Base class to test @EnableJdbcRepositories(queryLookupStrategy = ...) Tests based on logic from + * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy} + * + * @author Diego Krupitza + */ +abstract class AbstractJdbcRepositoryLookUpStrategyIntegrationTests { + + @Autowired protected OnesRepository onesRepository; + @Autowired NamedParameterJdbcTemplate template; + @Autowired RelationalMappingContext context; + + protected void insertTestInstances() { + AggregateOne firstAggregate = new AggregateOne("Diego"); + AggregateOne secondAggregate = new AggregateOne("Franz"); + AggregateOne thirdAggregate = new AggregateOne("Daniela"); + + onesRepository.saveAll(Arrays.asList(firstAggregate, secondAggregate, thirdAggregate)); + } + + protected void callDeclaredQuery(String name, int expectedSize, String... expectedNames) { + insertTestInstances(); + + List likeNameD = onesRepository.findAllByName(name); + + assertThat(likeNameD).hasSize(expectedSize); + + assertThat(likeNameD.stream().map(item -> item.name).collect(Collectors.toList())) // + .contains(expectedNames); + + } + + protected void callDerivedQuery() { + insertTestInstances(); + + AggregateOne diego = onesRepository.findByName("Diego"); + assertThat(diego).isNotNull(); + assertThat(diego.id).isNotNull(); + assertThat(diego.name).isEqualToIgnoringCase("Diego"); + } + + interface OnesRepository extends CrudRepository { + + // if derived is used it is just a basic findByName + // if declared is used it should be a like check + @Query("Select * from aggregate_one where NAME like concat('%', :name, '%') ") + List findAllByName(String name); + + AggregateOne findByName(String name); + } + + static class AggregateOne { + + @Id Long id; + String name; + + public AggregateOne(String name) { + this.name = name; + } + } +} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java new file mode 100644 index 0000000000..f435219790 --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; +import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.jdbc.testing.TestConfiguration; +import org.springframework.data.repository.query.QueryLookupStrategy; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +/** + * Test to verify that + * @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND) works as + * intended. Tests based on logic from + * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.CreateIfNotFoundQueryLookupStrategy} + * + * @author Diego Krupitza + */ +@ContextConfiguration +@Transactional +@ActiveProfiles("hsql") +@ExtendWith(SpringExtension.class) +class JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests + extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { + + @Test + void declaredQueryShouldWork() { + onesRepository.deleteAll(); + callDeclaredQuery("D", 2, "Diego", "Daniela"); + } + + @Test + void derivedQueryShouldWork() { + onesRepository.deleteAll(); + callDerivedQuery(); + } + + @Configuration + @Import(TestConfiguration.class) + @EnableJdbcRepositories(considerNestedRepositories = true, + queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, + includeFilters = @ComponentScan.Filter( + value = AbstractJdbcRepositoryLookUpStrategyIntegrationTests.OnesRepository.class, + type = FilterType.ASSIGNABLE_TYPE)) + static class Config { + + @Autowired JdbcRepositoryFactory factory; + + @Bean + Class testClass() { + return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + } + } + +} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java new file mode 100644 index 0000000000..59371955ef --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; +import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.jdbc.testing.TestConfiguration; +import org.springframework.data.repository.query.QueryLookupStrategy; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +/** + * Test to verify that @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE) works + * as intended. Tests based on logic from + * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.CreateQueryLookupStrategy} + * + * @author Diego Krupitza + */ +@ContextConfiguration +@Transactional +@ActiveProfiles("hsql") +@ExtendWith(SpringExtension.class) +class JdbcRepositoryCreateLookUpStrategyIntegrationTests extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { + + @Test + void declaredQueryShouldWork() { + onesRepository.deleteAll(); + + // here the declared query will use the dervice query which does something totally different + callDeclaredQuery("D", 0); + } + + @Test + void derivedQueryShouldWork() { + onesRepository.deleteAll(); + callDerivedQuery(); + } + + @Configuration + @Import(TestConfiguration.class) + @EnableJdbcRepositories(considerNestedRepositories = true, queryLookupStrategy = QueryLookupStrategy.Key.CREATE, + includeFilters = @ComponentScan.Filter(value = OnesRepository.class, type = FilterType.ASSIGNABLE_TYPE)) + static class Config { + + @Autowired JdbcRepositoryFactory factory; + + @Bean + Class testClass() { + return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + } + } + +} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java new file mode 100644 index 0000000000..40fd53eb69 --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java @@ -0,0 +1,60 @@ +package org.springframework.data.jdbc.repository; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; +import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.jdbc.testing.TestConfiguration; +import org.springframework.data.repository.query.QueryLookupStrategy; + +/** + * Test to verify that + * @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.USE_DECLARED_QUERY) works as + * intended. Tests based on logic from + * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.DeclaredQueryLookupStrategy} + * + * @author Diego Krupitza + */ +class JdbcRepositoryDeclaredLookUpStrategyIntegrationTests + extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { + + @Test + void contextCannotByCreatedDueToFindByNameNotDeclaredQuery() { + + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { + + context.register(JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.Config.class); + + assertThatThrownBy(() -> { + context.refresh(); + context.getBean(OnesRepository.class); + }).hasMessageContaining("findByName"); + } + } + + @Configuration + @Import(TestConfiguration.class) + @EnableJdbcRepositories(considerNestedRepositories = true, + queryLookupStrategy = QueryLookupStrategy.Key.USE_DECLARED_QUERY, + includeFilters = @ComponentScan.Filter( + value = AbstractJdbcRepositoryLookUpStrategyIntegrationTests.OnesRepository.class, + type = FilterType.ASSIGNABLE_TYPE)) + static class Config { + + @Autowired JdbcRepositoryFactory factory; + + @Bean + Class testClass() { + return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + } + } + +} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java index c32c22ca11..4b2187c776 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,20 @@ */ package org.springframework.data.jdbc.repository.support; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.lang.reflect.Method; import java.text.NumberFormat; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.repository.QueryMappingConfiguration; @@ -35,6 +40,7 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.util.ClassTypeInformation; import org.springframework.jdbc.core.RowMapper; @@ -52,6 +58,7 @@ * @author Evgeni Dimitrov * @author Mark Paluch * @author Hebert Coelho + * @author Diego Krupitza */ class JdbcQueryLookupStrategyUnitTests { @@ -81,7 +88,8 @@ void typeBasedRowMapperGetsUsedForQuery() { QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration() .registerRowMapper(NumberFormat.class, numberFormatMapper); - RepositoryQuery repositoryQuery = getRepositoryQuery("returningNumberFormat", mappingConfiguration); + RepositoryQuery repositoryQuery = getRepositoryQuery(QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, + "returningNumberFormat", mappingConfiguration); repositoryQuery.execute(new Object[] {}); @@ -95,16 +103,55 @@ void prefersDeclaredQuery() { QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration() .registerRowMapper(NumberFormat.class, numberFormatMapper); - RepositoryQuery repositoryQuery = getRepositoryQuery("annotatedQueryWithQueryAndQueryName", mappingConfiguration); + RepositoryQuery repositoryQuery = getRepositoryQuery(QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, + "annotatedQueryWithQueryAndQueryName", mappingConfiguration); repositoryQuery.execute(new Object[] {}); verify(operations).queryForObject(eq("some SQL"), any(SqlParameterSource.class), any(RowMapper.class)); } - private RepositoryQuery getRepositoryQuery(String name, QueryMappingConfiguration mappingConfiguration) { + @Test + void shouldFailOnMissingDeclaredQuery() { - JdbcQueryLookupStrategy queryLookupStrategy = new JdbcQueryLookupStrategy(publisher, callbacks, mappingContext, + RowMapper numberFormatMapper = mock(RowMapper.class); + QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration() + .registerRowMapper(NumberFormat.class, numberFormatMapper); + + assertThatThrownBy( + () -> getRepositoryQuery(QueryLookupStrategy.Key.USE_DECLARED_QUERY, "findByName", mappingConfiguration)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Did neither find a NamedQuery nor an annotated query for method") + .hasMessageContaining("findByName"); + } + + @ParameterizedTest + @MethodSource("correctLookUpStrategyForKeySource") + void correctLookUpStrategyForKey(QueryLookupStrategy.Key key, Class expectedClass) { + RowMapper numberFormatMapper = mock(RowMapper.class); + QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration() + .registerRowMapper(NumberFormat.class, numberFormatMapper); + + QueryLookupStrategy queryLookupStrategy = JdbcQueryLookupStrategy.create(key, publisher, callbacks, mappingContext, + converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null); + + assertThat(queryLookupStrategy).isInstanceOf(expectedClass); + } + + private static Stream correctLookUpStrategyForKeySource() { + return Stream.of( // + Arguments.of(QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, + JdbcQueryLookupStrategy.CreateIfNotFoundQueryLookupStrategy.class), // + Arguments.of(QueryLookupStrategy.Key.CREATE, JdbcQueryLookupStrategy.CreateQueryLookupStrategy.class), // + Arguments.of(QueryLookupStrategy.Key.USE_DECLARED_QUERY, + JdbcQueryLookupStrategy.DeclaredQueryLookupStrategy.class) // + ); + } + + private RepositoryQuery getRepositoryQuery(QueryLookupStrategy.Key key, String name, + QueryMappingConfiguration mappingConfiguration) { + + QueryLookupStrategy queryLookupStrategy = JdbcQueryLookupStrategy.create(key, publisher, callbacks, mappingContext, converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null); Method method = ReflectionUtils.findMethod(MyRepository.class, name); @@ -119,5 +166,7 @@ interface MyRepository { @Query(value = "some SQL", name = "query-name") void annotatedQueryWithQueryAndQueryName(); + + NumberFormat findByName(); } } diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql new file mode 100644 index 0000000000..205dff68d4 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql @@ -0,0 +1,7 @@ +DROP TABLE aggregate_one; + +CREATE TABLE aggregate_one +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + NAME VARCHAR(100) +); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql new file mode 100644 index 0000000000..6ab837bf09 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql @@ -0,0 +1,5 @@ +CREATE TABLE aggregate_one +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + NAME VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql new file mode 100644 index 0000000000..8e5b1318ac --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql @@ -0,0 +1,5 @@ +CREATE TABLE aggregate_one +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + NAME VARCHAR(100) +); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql new file mode 100644 index 0000000000..1e08bbef5e --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql @@ -0,0 +1,5 @@ +CREATE TABLE aggregate_one +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(100) +); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql new file mode 100644 index 0000000000..e6eee1fd7a --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS aggregate_one; + +CREATE TABLE aggregate_one +( + id BIGINT IDENTITY PRIMARY KEY, + NAME VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql new file mode 100644 index 0000000000..53c5933b59 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql @@ -0,0 +1,5 @@ +CREATE TABLE aggregate_one +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + NAME VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql new file mode 100644 index 0000000000..d32bc37643 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql @@ -0,0 +1,7 @@ +DROP TABLE aggregate_one CASCADE CONSTRAINTS PURGE; + +CREATE TABLE aggregate_one +( + id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, + NAME VARCHAR2(100) +); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql new file mode 100644 index 0000000000..c551f53fa0 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql @@ -0,0 +1,6 @@ +DROP TABLE aggregate_one; +CREATE TABLE aggregate_one +( + id SERIAL PRIMARY KEY, + NAME VARCHAR(100) +); \ No newline at end of file From b4d3838d65c4d64baa626816593ec4aa312edce2 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 7 Mar 2022 14:26:22 +0100 Subject: [PATCH 42/51] Polishing. Run tests only for a single database since it is actually not testing anything database related. Formatting. Original pull request #1187 See #1043 --- .../config/EnableJdbcRepositories.java | 2 ++ .../support/JdbcQueryLookupStrategy.java | 35 ++++++++----------- ...actJdbcRepositoryLookUpStrategyTests.java} | 12 ++++--- ...yCreateIfNotFoundLookUpStrategyTests.java} | 19 +++++----- ...cRepositoryCreateLookUpStrategyTests.java} | 15 ++++---- ...epositoryDeclaredLookUpStrategyTests.java} | 16 ++++----- .../JdbcQueryLookupStrategyUnitTests.java | 3 +- ...toryLookUpStrategyIntegrationTests-db2.sql | 7 ---- ...itoryLookUpStrategyIntegrationTests-h2.sql | 5 --- ...LookUpStrategyIntegrationTests-mariadb.sql | 5 --- ...ryLookUpStrategyIntegrationTests-mssql.sql | 7 ---- ...ryLookUpStrategyIntegrationTests-mysql.sql | 5 --- ...yLookUpStrategyIntegrationTests-oracle.sql | 7 ---- ...ookUpStrategyIntegrationTests-postgres.sql | 6 ---- ...dbcRepositoryLookUpStrategyTests-hsql.sql} | 0 15 files changed, 48 insertions(+), 96 deletions(-) rename spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/{AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java => AbstractJdbcRepositoryLookUpStrategyTests.java} (89%) rename spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/{JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java => JdbcRepositoryCreateIfNotFoundLookUpStrategyTests.java} (81%) rename spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/{JdbcRepositoryCreateLookUpStrategyIntegrationTests.java => JdbcRepositoryCreateLookUpStrategyTests.java} (84%) rename spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/{JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java => JdbcRepositoryDeclaredLookUpStrategyTests.java} (76%) delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql rename spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/{AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql => AbstractJdbcRepositoryLookUpStrategyTests-hsql.sql} (100%) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java index c5e1694508..10752cc8df 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositories.java @@ -136,6 +136,8 @@ /** * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to * {@link QueryLookupStrategy.Key#CREATE_IF_NOT_FOUND}. + * + * @since 2.1 */ QueryLookupStrategy.Key queryLookupStrategy() default QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java index 4fbdd69f86..a854b99c3c 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java @@ -99,6 +99,7 @@ abstract class JdbcQueryLookupStrategy implements QueryLookupStrategy { * {@link QueryLookupStrategy} to create a query from the method name. * * @author Diego Krupitza + * @since 2.4 */ static class CreateQueryLookupStrategy extends JdbcQueryLookupStrategy { @@ -125,6 +126,7 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repository * {@link org.springframework.data.jdbc.repository.query.Query} annotation followed by a JPA named query lookup. * * @author Diego Krupitza + * @since 2.4 */ static class DeclaredQueryLookupStrategy extends JdbcQueryLookupStrategy { @@ -150,7 +152,7 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repository StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, getOperations(), this::createMapper, getConverter()); - query.setBeanFactory(getBeanfactory()); + query.setBeanFactory(getBeanFactory()); return query; } @@ -163,12 +165,9 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repository * {@link QueryLookupStrategy} to try to detect a declared query first ( * {@link org.springframework.data.jdbc.repository.query.Query}, JDBC named query). In case none is found we fall back * on query creation. - *

- * Modified based on original source: {@link org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy} * - * @author Oliver Gierke - * @author Thomas Darimont * @author Diego Krupitza + * @since 2.4 */ static class CreateIfNotFoundQueryLookupStrategy extends JdbcQueryLookupStrategy { @@ -181,7 +180,7 @@ static class CreateIfNotFoundQueryLookupStrategy extends JdbcQueryLookupStrategy * @param createStrategy must not be {@literal null}. * @param lookupStrategy must not be {@literal null}. */ - public CreateIfNotFoundQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, + CreateIfNotFoundQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, RelationalMappingContext context, JdbcConverter converter, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, @Nullable BeanFactory beanfactory, CreateQueryLookupStrategy createStrategy, @@ -228,12 +227,12 @@ JdbcQueryMethod getJdbcQueryMethod(Method method, RepositoryMetadata repositoryM * @param dialect must not be {@literal null} * @param queryMappingConfiguration must not be {@literal null} * @param operations must not be {@literal null} - * @param beanfactory may be {@literal null} + * @param beanFactory may be {@literal null} */ public static QueryLookupStrategy create(@Nullable Key key, ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks, RelationalMappingContext context, JdbcConverter converter, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations, - @Nullable BeanFactory beanfactory) { + @Nullable BeanFactory beanFactory) { Assert.notNull(publisher, "ApplicationEventPublisher must not be null"); Assert.notNull(context, "RelationalMappingContextPublisher must not be null"); @@ -243,10 +242,10 @@ public static QueryLookupStrategy create(@Nullable Key key, ApplicationEventPubl Assert.notNull(operations, "NamedParameterJdbcOperations must not be null"); CreateQueryLookupStrategy createQueryLookupStrategy = new CreateQueryLookupStrategy(publisher, callbacks, context, - converter, dialect, queryMappingConfiguration, operations, beanfactory); + converter, dialect, queryMappingConfiguration, operations, beanFactory); DeclaredQueryLookupStrategy declaredQueryLookupStrategy = new DeclaredQueryLookupStrategy(publisher, callbacks, - context, converter, dialect, queryMappingConfiguration, operations, beanfactory); + context, converter, dialect, queryMappingConfiguration, operations, beanFactory); Key cleanedKey = key != null ? key : Key.CREATE_IF_NOT_FOUND; @@ -259,34 +258,30 @@ public static QueryLookupStrategy create(@Nullable Key key, ApplicationEventPubl return declaredQueryLookupStrategy; case CREATE_IF_NOT_FOUND: return new CreateIfNotFoundQueryLookupStrategy(publisher, callbacks, context, converter, dialect, - queryMappingConfiguration, operations, beanfactory, createQueryLookupStrategy, declaredQueryLookupStrategy); + queryMappingConfiguration, operations, beanFactory, createQueryLookupStrategy, declaredQueryLookupStrategy); default: throw new IllegalArgumentException(String.format("Unsupported query lookup strategy %s!", key)); } } - protected ApplicationEventPublisher getPublisher() { - return publisher; - } - - protected RelationalMappingContext getContext() { + RelationalMappingContext getContext() { return context; } - protected JdbcConverter getConverter() { + JdbcConverter getConverter() { return converter; } - protected Dialect getDialect() { + Dialect getDialect() { return dialect; } - protected NamedParameterJdbcOperations getOperations() { + NamedParameterJdbcOperations getOperations() { return operations; } @Nullable - protected BeanFactory getBeanfactory() { + BeanFactory getBeanFactory() { return beanfactory; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyTests.java similarity index 89% rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyTests.java index 41e5646c98..8193b0c657 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/AbstractJdbcRepositoryLookUpStrategyTests.java @@ -29,18 +29,19 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** - * Base class to test @EnableJdbcRepositories(queryLookupStrategy = ...) Tests based on logic from - * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy} + * Base class to test @EnableJdbcRepositories(queryLookupStrategy = ...) * * @author Diego Krupitza + * @since 2.4 */ -abstract class AbstractJdbcRepositoryLookUpStrategyIntegrationTests { +abstract class AbstractJdbcRepositoryLookUpStrategyTests { @Autowired protected OnesRepository onesRepository; @Autowired NamedParameterJdbcTemplate template; @Autowired RelationalMappingContext context; - protected void insertTestInstances() { + void insertTestInstances() { + AggregateOne firstAggregate = new AggregateOne("Diego"); AggregateOne secondAggregate = new AggregateOne("Franz"); AggregateOne thirdAggregate = new AggregateOne("Daniela"); @@ -48,7 +49,8 @@ protected void insertTestInstances() { onesRepository.saveAll(Arrays.asList(firstAggregate, secondAggregate, thirdAggregate)); } - protected void callDeclaredQuery(String name, int expectedSize, String... expectedNames) { + void callDeclaredQuery(String name, int expectedSize, String... expectedNames) { + insertTestInstances(); List likeNameD = onesRepository.findAllByName(name); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyTests.java similarity index 81% rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyTests.java index f435219790..43f264b59e 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateIfNotFoundLookUpStrategyTests.java @@ -27,7 +27,6 @@ import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; @@ -35,25 +34,24 @@ /** * Test to verify that * @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND) works as - * intended. Tests based on logic from - * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.CreateIfNotFoundQueryLookupStrategy} + * intended. * * @author Diego Krupitza + * @author Jens Schauder */ @ContextConfiguration @Transactional -@ActiveProfiles("hsql") @ExtendWith(SpringExtension.class) -class JdbcRepositoryCreateIfNotFoundLookUpStrategyIntegrationTests - extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { +class JdbcRepositoryCreateIfNotFoundLookUpStrategyTests + extends AbstractJdbcRepositoryLookUpStrategyTests { - @Test + @Test // GH-1043 void declaredQueryShouldWork() { onesRepository.deleteAll(); callDeclaredQuery("D", 2, "Diego", "Daniela"); } - @Test + @Test // GH-1043 void derivedQueryShouldWork() { onesRepository.deleteAll(); callDerivedQuery(); @@ -64,7 +62,7 @@ void derivedQueryShouldWork() { @EnableJdbcRepositories(considerNestedRepositories = true, queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, includeFilters = @ComponentScan.Filter( - value = AbstractJdbcRepositoryLookUpStrategyIntegrationTests.OnesRepository.class, + value = AbstractJdbcRepositoryLookUpStrategyTests.OnesRepository.class, type = FilterType.ASSIGNABLE_TYPE)) static class Config { @@ -72,8 +70,7 @@ static class Config { @Bean Class testClass() { - return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + return AbstractJdbcRepositoryLookUpStrategyTests.class; } } - } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyTests.java similarity index 84% rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyTests.java index 59371955ef..77d7f81098 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCreateLookUpStrategyTests.java @@ -34,26 +34,25 @@ /** * Test to verify that @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE) works - * as intended. Tests based on logic from - * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.CreateQueryLookupStrategy} + * as intended. * * @author Diego Krupitza + * @author Jens Schauder */ @ContextConfiguration @Transactional -@ActiveProfiles("hsql") @ExtendWith(SpringExtension.class) -class JdbcRepositoryCreateLookUpStrategyIntegrationTests extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { +class JdbcRepositoryCreateLookUpStrategyTests extends AbstractJdbcRepositoryLookUpStrategyTests { - @Test + @Test // GH-1043 void declaredQueryShouldWork() { onesRepository.deleteAll(); - // here the declared query will use the dervice query which does something totally different + // here the declared query will use the derived query which does something totally different callDeclaredQuery("D", 0); } - @Test + @Test // GH-1043 void derivedQueryShouldWork() { onesRepository.deleteAll(); callDerivedQuery(); @@ -69,7 +68,7 @@ static class Config { @Bean Class testClass() { - return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + return AbstractJdbcRepositoryLookUpStrategyTests.class; } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyTests.java similarity index 76% rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyTests.java index 40fd53eb69..83ac2f97a7 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryDeclaredLookUpStrategyTests.java @@ -18,20 +18,19 @@ /** * Test to verify that * @EnableJdbcRepositories(queryLookupStrategy = QueryLookupStrategy.Key.USE_DECLARED_QUERY) works as - * intended. Tests based on logic from - * {@link org.springframework.data.jdbc.repository.support.JdbcQueryLookupStrategy.DeclaredQueryLookupStrategy} + * intended. * * @author Diego Krupitza */ -class JdbcRepositoryDeclaredLookUpStrategyIntegrationTests - extends AbstractJdbcRepositoryLookUpStrategyIntegrationTests { +class JdbcRepositoryDeclaredLookUpStrategyTests + extends AbstractJdbcRepositoryLookUpStrategyTests { - @Test + @Test // GH-1043 void contextCannotByCreatedDueToFindByNameNotDeclaredQuery() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { - context.register(JdbcRepositoryDeclaredLookUpStrategyIntegrationTests.Config.class); + context.register(JdbcRepositoryDeclaredLookUpStrategyTests.Config.class); assertThatThrownBy(() -> { context.refresh(); @@ -45,7 +44,7 @@ void contextCannotByCreatedDueToFindByNameNotDeclaredQuery() { @EnableJdbcRepositories(considerNestedRepositories = true, queryLookupStrategy = QueryLookupStrategy.Key.USE_DECLARED_QUERY, includeFilters = @ComponentScan.Filter( - value = AbstractJdbcRepositoryLookUpStrategyIntegrationTests.OnesRepository.class, + value = AbstractJdbcRepositoryLookUpStrategyTests.OnesRepository.class, type = FilterType.ASSIGNABLE_TYPE)) static class Config { @@ -53,8 +52,7 @@ static class Config { @Bean Class testClass() { - return AbstractJdbcRepositoryLookUpStrategyIntegrationTests.class; + return AbstractJdbcRepositoryLookUpStrategyTests.class; } } - } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java index 4b2187c776..170c052009 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java @@ -111,7 +111,7 @@ void prefersDeclaredQuery() { verify(operations).queryForObject(eq("some SQL"), any(SqlParameterSource.class), any(RowMapper.class)); } - @Test + @Test // GH-1043 void shouldFailOnMissingDeclaredQuery() { RowMapper numberFormatMapper = mock(RowMapper.class); @@ -139,6 +139,7 @@ void correctLookUpStrategyForKey(QueryLookupStrategy.Key key, Class expectedClas } private static Stream correctLookUpStrategyForKeySource() { + return Stream.of( // Arguments.of(QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, JdbcQueryLookupStrategy.CreateIfNotFoundQueryLookupStrategy.class), // diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql deleted file mode 100644 index 205dff68d4..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-db2.sql +++ /dev/null @@ -1,7 +0,0 @@ -DROP TABLE aggregate_one; - -CREATE TABLE aggregate_one -( - id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, - NAME VARCHAR(100) -); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql deleted file mode 100644 index 6ab837bf09..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-h2.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE aggregate_one -( - id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, - NAME VARCHAR(100) -); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql deleted file mode 100644 index 1e08bbef5e..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mariadb.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE aggregate_one -( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - NAME VARCHAR(100) -); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql deleted file mode 100644 index e6eee1fd7a..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mssql.sql +++ /dev/null @@ -1,7 +0,0 @@ -DROP TABLE IF EXISTS aggregate_one; - -CREATE TABLE aggregate_one -( - id BIGINT IDENTITY PRIMARY KEY, - NAME VARCHAR(100) -); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql deleted file mode 100644 index 53c5933b59..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-mysql.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE aggregate_one -( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - NAME VARCHAR(100) -); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql deleted file mode 100644 index d32bc37643..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-oracle.sql +++ /dev/null @@ -1,7 +0,0 @@ -DROP TABLE aggregate_one CASCADE CONSTRAINTS PURGE; - -CREATE TABLE aggregate_one -( - id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, - NAME VARCHAR2(100) -); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql deleted file mode 100644 index c551f53fa0..0000000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-postgres.sql +++ /dev/null @@ -1,6 +0,0 @@ -DROP TABLE aggregate_one; -CREATE TABLE aggregate_one -( - id SERIAL PRIMARY KEY, - NAME VARCHAR(100) -); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyTests-hsql.sql similarity index 100% rename from spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyIntegrationTests-hsql.sql rename to spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/AbstractJdbcRepositoryLookUpStrategyTests-hsql.sql From bfba4222f875785eefa3f235a82ae68c5bcd6c1e Mon Sep 17 00:00:00 2001 From: Meng Zuozhu Date: Tue, 8 Mar 2022 20:48:23 +0800 Subject: [PATCH 43/51] Fix toString for negated conditions. Original pull request #1193 --- .../org/springframework/data/relational/core/sql/Between.java | 3 ++- .../org/springframework/data/relational/core/sql/Like.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java index a6cd1eb95b..461447a087 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Between.java @@ -23,6 +23,7 @@ * Results in a rendered condition: {@code BETWEEN AND }. * * @author Mark Paluch + * @author Meng Zuozhu * @since 2.2 */ public class Between extends AbstractSegment implements Condition { @@ -91,6 +92,6 @@ public Between not() { @Override public String toString() { - return column + " BETWEEN " + begin + " AND " + end; + return column + (negated ? " NOT" : "") + " BETWEEN " + begin + " AND " + end; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java index aeccda54d9..8c1bc07f47 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/Like.java @@ -23,6 +23,7 @@ * Results in a rendered condition: {@code LIKE }. * * @author Mark Paluch + * @author Meng Zuozhu * @since 1.1 */ public class Like extends AbstractSegment implements Condition { @@ -80,6 +81,6 @@ public Like not() { @Override public String toString() { - return left + " LIKE " + right; + return left + (negated ? " NOT" : "") + " LIKE " + right; } } From 676cae25ba8e6616a2726642c39a6eaef3d71b57 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Fri, 11 Mar 2022 16:16:56 +0100 Subject: [PATCH 44/51] Support of `QueryByExampleExecutor#findOne(Example example)`. This commit introduces the find by example method `findOne(Example example)` to spring-data-jdbc. MyBatis implementation is missing since I do not have the knowledge for this. Related tickets #1192 --- .../jdbc/core/JdbcAggregateOperations.java | 13 +++ .../data/jdbc/core/JdbcAggregateTemplate.java | 16 ++++ .../convert/CascadingDataAccessStrategy.java | 8 ++ .../jdbc/core/convert/DataAccessStrategy.java | 13 +++ .../convert/DefaultDataAccessStrategy.java | 27 +++++- .../convert/DelegatingDataAccessStrategy.java | 9 ++ .../data/jdbc/core/convert/SqlGenerator.java | 92 +++++++++++++++---- .../mybatis/MyBatisDataAccessStrategy.java | 9 ++ .../jdbc/repository/query/QueryMapper.java | 8 +- .../support/SimpleJdbcRepository.java | 72 ++++++++++++++- .../JdbcRepositoryIntegrationTests.java | 59 +++++++++++- 11 files changed, 299 insertions(+), 27 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index 73cc729525..a65146120b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -15,6 +15,9 @@ */ package org.springframework.data.jdbc.core; +import java.util.Optional; + +import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -26,6 +29,7 @@ * @author Jens Schauder * @author Thomas Lang * @author Milan Milanov + * @author Diego Krupitza */ public interface JdbcAggregateOperations { @@ -154,4 +158,13 @@ public interface JdbcAggregateOperations { * @since 2.0 */ Page findAll(Class domainType, Pageable pageable); + + /** + * Execute a {@code SELECT} query and convert the resulting item to an entity ensuring exactly one result. + * + * @param example must not be null + * @return exactly one result or {@link Optional#empty()} if no match found. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + Optional selectOne(Example example); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index eab91a0d97..1ec9d49713 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -17,12 +17,14 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -38,6 +40,8 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.event.*; +import org.springframework.data.relational.core.query.Query; +import org.springframework.data.relational.repository.query.RelationalExampleMapper; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -51,6 +55,7 @@ * @author Christoph Strobl * @author Milan Milanov * @author Myeonghyeon Lee + * @author Diego Krupitza */ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -63,6 +68,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { private final DataAccessStrategy accessStrategy; private final AggregateChangeExecutor executor; + private final RelationalExampleMapper exampleMapper; private EntityCallbacks entityCallbacks = EntityCallbacks.create(); @@ -92,6 +98,7 @@ public JdbcAggregateTemplate(ApplicationContext publisher, RelationalMappingCont this.jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter(context); this.executor = new AggregateChangeExecutor(converter, accessStrategy); + this.exampleMapper = new RelationalExampleMapper(converter.getMappingContext()); setEntityCallbacks(EntityCallbacks.create(publisher)); } @@ -120,6 +127,7 @@ public JdbcAggregateTemplate(ApplicationEventPublisher publisher, RelationalMapp this.jdbcEntityUpdateWriter = new RelationalEntityUpdateWriter(context); this.jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter(context); this.executor = new AggregateChangeExecutor(converter, accessStrategy); + this.exampleMapper = new RelationalExampleMapper(converter.getMappingContext()); } /** @@ -254,6 +262,14 @@ public Page findAll(Class domainType, Pageable pageable) { return PageableExecutionUtils.getPage(content, pageable, () -> accessStrategy.count(domainType)); } + @Override + public Optional selectOne(Example example) { + Query query = this.exampleMapper.getMappedExample(example); + Class probeType = example.getProbeType(); + + return accessStrategy.selectOne(query, probeType); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.JdbcAggregateOperations#findAll(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java index e24b3bf6ce..34b5aa0f8f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; @@ -24,6 +25,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.LockMode; /** @@ -35,6 +37,7 @@ * @author Tyler Van Gorder * @author Milan Milanov * @author Myeonghyeon Lee + * @author Diego Krupitza * @since 1.1 */ public class CascadingDataAccessStrategy implements DataAccessStrategy { @@ -208,6 +211,11 @@ public Iterable findAll(Class domainType, Pageable pageable) { return collect(das -> das.findAll(domainType, pageable)); } + @Override + public Optional selectOne(Query query, Class probeType) { + return collect(das -> das.selectOne(query, probeType)); + } + private T collect(Function function) { // Keep as Eclipse fails to compile if <> is used. diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java index 78bb984c06..509e8bce2e 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java @@ -16,13 +16,16 @@ package org.springframework.data.jdbc.core.convert; import java.util.Map; +import java.util.Optional; +import org.springframework.dao.DataAccessException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.JdbcAggregateOperations; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.lang.Nullable; @@ -35,6 +38,7 @@ * @author Tyler Van Gorder * @author Milan Milanov * @author Myeonghyeon Lee + * @author Diego Krupitza */ public interface DataAccessStrategy extends RelationResolver { @@ -226,4 +230,13 @@ Iterable findAllByPath(Identifier identifier, * @since 2.0 */ Iterable findAll(Class domainType, Pageable pageable); + + /** + * Execute a {@code SELECT} query and convert the resulting item to an entity ensuring exactly one result. + * + * @param query must not be {@literal null}. + * @return exactly one result or {@link Optional#empty()} if no match found. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + Optional selectOne(Query query, Class probeType); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index 151c77027a..a4b879a727 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Predicate; import org.springframework.dao.DataRetrievalFailureException; @@ -42,10 +43,12 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -68,6 +71,7 @@ * @author Myeonghyeon Lee * @author Yunyoung LEE * @author Radim Tlusty + * @author Diego Krupitza * @since 1.1 */ public class DefaultDataAccessStrategy implements DataAccessStrategy { @@ -134,7 +138,8 @@ public Object insert(T instance, Class domainType, Identifier identifier) } @Nullable - private Object executeInsertAndReturnGeneratedId(Class domainType, RelationalPersistentEntity persistentEntity, SqlIdentifierParameterSource parameterSource, String insertSql) { + private Object executeInsertAndReturnGeneratedId(Class domainType, + RelationalPersistentEntity persistentEntity, SqlIdentifierParameterSource parameterSource, String insertSql) { KeyHolder holder = new GeneratedKeyHolder(); @@ -429,6 +434,21 @@ public Iterable findAll(Class domainType, Pageable pageable) { return operations.query(sql(domainType).getFindAll(pageable), (RowMapper) getEntityRowMapper(domainType)); } + @Override + public Optional selectOne(Query query, Class probeType) { + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + String sqlQuery = sql(probeType).selectOne(query, parameterSource); + + T foundObject; + try { + foundObject = operations.queryForObject(sqlQuery, parameterSource, (RowMapper) getEntityRowMapper(probeType)); + } catch (EmptyResultDataAccessException e) { + foundObject = null; + } + + return Optional.ofNullable(foundObject); + } + private SqlIdentifierParameterSource getParameterSource(@Nullable S instance, RelationalPersistentEntity persistentEntity, String prefix, Predicate skipProperty, IdentifierProcessing identifierProcessing) { @@ -546,7 +566,8 @@ private IdentifierProcessing getIdentifierProcessing() { private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSource, RelationalPersistentProperty property, @Nullable Object value, SqlIdentifier name) { - addConvertedValue(parameterSource, value, name, converter.getColumnType(property), converter.getTargetSqlType(property)); + addConvertedValue(parameterSource, value, name, converter.getColumnType(property), + converter.getTargetSqlType(property)); } private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSource, SqlIdentifier name, Object value, @@ -556,7 +577,7 @@ private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSou } private void addConvertedValue(SqlIdentifierParameterSource parameterSource, @Nullable Object value, - SqlIdentifier paramName, Class javaType, SQLType sqlType) { + SqlIdentifier paramName, Class javaType, SQLType sqlType) { JdbcValue jdbcValue = converter.writeJdbcValue( // value, // diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java index 1a917409c4..94105c2950 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java @@ -19,9 +19,12 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.util.Assert; +import java.util.Optional; + /** * Delegates all method calls to an instance set after construction. This is useful for {@link DataAccessStrategy}s with * cyclic dependencies. @@ -30,6 +33,7 @@ * @author Tyler Van Gorder * @author Milan Milanov * @author Myeonghyeon Lee + * @author Diego Krupitza * @since 1.1 */ public class DelegatingDataAccessStrategy implements DataAccessStrategy { @@ -203,6 +207,11 @@ public Iterable findAll(Class domainType, Pageable pageable) { return delegate.findAll(domainType, pageable); } + @Override + public Optional selectOne(Query query, Class probeType) { + return delegate.selectOne(query, probeType); + } + /** * Must be called exactly once before calling any of the other methods. * diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index a95c9b1933..7431cc3b26 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -15,8 +15,14 @@ */ package org.springframework.data.jdbc.core.convert; +import java.util.*; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.jdbc.repository.query.QueryMapper; import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; @@ -26,18 +32,16 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.CriteriaDefinition; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.*; import org.springframework.data.relational.core.sql.render.RenderContext; import org.springframework.data.relational.core.sql.render.SqlRenderer; import org.springframework.data.util.Lazy; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import java.util.*; -import java.util.function.Function; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - /** * Generates SQL statements to be used by {@link SimpleJdbcRepository} * @@ -52,6 +56,7 @@ * @author Myeonghyeon Lee * @author Mikhail Polivakha * @author Chirag Tailor + * @author Diego Krupitza */ class SqlGenerator { @@ -82,6 +87,7 @@ class SqlGenerator { private final Lazy deleteByIdSql = Lazy.of(this::createDeleteSql); private final Lazy deleteByIdAndVersionSql = Lazy.of(this::createDeleteByIdAndVersionSql); private final Lazy deleteByListSql = Lazy.of(this::createDeleteByListSql); + private final QueryMapper queryMapper; /** * Create a new {@link SqlGenerator} given {@link RelationalMappingContext} and {@link RelationalPersistentEntity}. @@ -100,6 +106,7 @@ class SqlGenerator { this.renderContext = new RenderContextFactory(dialect).createRenderContext(); this.sqlRenderer = SqlRenderer.create(renderContext); this.columns = new Columns(entity, mappingContext, converter); + this.queryMapper = new QueryMapper(dialect, converter); } /** @@ -383,11 +390,11 @@ private String createAcquireLockById(LockMode lockMode) { Table table = this.getTable(); Select select = StatementBuilder // - .select(getIdColumn()) // - .from(table) // - .where(getIdColumn().isEqualTo(getBindMarker(ID_SQL_PARAMETER))) // - .lock(lockMode) // - .build(); + .select(getIdColumn()) // + .from(table) // + .where(getIdColumn().isEqualTo(getBindMarker(ID_SQL_PARAMETER))) // + .lock(lockMode) // + .build(); return render(select); } @@ -397,10 +404,10 @@ private String createAcquireLockAll(LockMode lockMode) { Table table = this.getTable(); Select select = StatementBuilder // - .select(getIdColumn()) // - .from(table) // - .lock(lockMode) // - .build(); + .select(getIdColumn()) // + .from(table) // + .lock(lockMode) // + .build(); return render(select); } @@ -718,6 +725,57 @@ private OrderByField orderToOrderByField(Sort.Order order) { return OrderByField.from(column, order.getDirection()).withNullHandling(order.getNullHandling()); } + /** + * Constructs a single sql query that performs select based on the provided query. Additional the bindings for the + * where clause are stored after execution into the parameterSource + * + * @param query the query to base the select on. Must not be null + * @param parameterSource the source for holding the bindings + * @return a non null query string. + */ + public String selectOne(Query query, MapSqlParameterSource parameterSource) { + + Assert.notNull(parameterSource, "parameterSource must not be null"); + + Table table = Table.create(this.entity.getTableName()); + + SelectBuilder.SelectWhere selectBuilder = selectBuilder(); + + SelectBuilder.SelectOrdered selectOrdered = query // + .getCriteria() // + .map(item -> this.applyCriteria(item, selectBuilder, parameterSource, table)) // + .orElse(selectBuilder); + + if (query.isSorted()) { + List sort = this.queryMapper.getMappedSort(table, query.getSort(), entity); + selectOrdered = selectBuilder.orderBy(sort); + } + + SelectBuilder.SelectLimitOffset limitable = (SelectBuilder.SelectLimitOffset) selectOrdered; + + if (query.getLimit() > 0) { + limitable = limitable.limit(query.getLimit()); + } + + if (query.getOffset() > 0) { + limitable = limitable.offset(query.getOffset()); + } + + selectOrdered = (SelectBuilder.SelectOrdered) limitable; + Select select = selectOrdered // + .build(); + + return render(select); + } + + SelectBuilder.SelectOrdered applyCriteria(@Nullable CriteriaDefinition criteria, + SelectBuilder.SelectWhere whereBuilder, MapSqlParameterSource parameterSource, Table table) { + + return criteria != null // + ? whereBuilder.where(queryMapper.getMappedObject(parameterSource, criteria, table, entity)) // + : whereBuilder; + } + /** * Value object representing a {@code JOIN} association. */ @@ -729,9 +787,9 @@ static final class Join { Join(Table joinTable, Column joinColumn, Column parentId) { - Assert.notNull( joinTable,"JoinTable must not be null."); - Assert.notNull( joinColumn,"JoinColumn must not be null."); - Assert.notNull( parentId,"ParentId must not be null."); + Assert.notNull(joinTable, "JoinTable must not be null."); + Assert.notNull(joinColumn, "JoinColumn must not be null."); + Assert.notNull(parentId, "ParentId must not be null."); this.joinTable = joinTable; this.joinColumn = joinColumn; diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index 0a5569d830..c94118d654 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.ibatis.session.SqlSession; @@ -41,6 +42,7 @@ import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.SqlIdentifier; @@ -365,6 +367,13 @@ public Iterable findAll(Class domainType, Pageable pageable) { new MyBatisContext(null, null, domainType, additionalContext)); } + @Override + public Optional selectOne(Query query, Class probeType) { + // TODO: DIEGO find help for this one + // I have zero MyBatis knowledge. + return Optional.empty(); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.DataAccessStrategy#count(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java index d674417d37..63f6341d7a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java @@ -58,7 +58,7 @@ * @author Jens Schauder * @since 2.0 */ -class QueryMapper { +public class QueryMapper { private final JdbcConverter converter; private final Dialect dialect; @@ -71,7 +71,7 @@ class QueryMapper { * @param converter must not be {@literal null}. */ @SuppressWarnings({ "unchecked", "rawtypes" }) - QueryMapper(Dialect dialect, JdbcConverter converter) { + public QueryMapper(Dialect dialect, JdbcConverter converter) { Assert.notNull(dialect, "Dialect must not be null!"); Assert.notNull(converter, "JdbcConverter must not be null!"); @@ -88,7 +88,7 @@ class QueryMapper { * @param entity related {@link RelationalPersistentEntity}, can be {@literal null}. * @return */ - List getMappedSort(Table table, Sort sort, @Nullable RelationalPersistentEntity entity) { + public List getMappedSort(Table table, Sort sort, @Nullable RelationalPersistentEntity entity) { List mappedOrder = new ArrayList<>(); @@ -157,7 +157,7 @@ Expression getMappedObject(Expression expression, @Nullable RelationalPersistent * @param entity related {@link RelationalPersistentEntity}, can be {@literal null}. * @return the mapped {@link Condition}. */ - Condition getMappedObject(MapSqlParameterSource parameterSource, CriteriaDefinition criteria, Table table, + public Condition getMappedObject(MapSqlParameterSource parameterSource, CriteriaDefinition criteria, Table table, @Nullable RelationalPersistentEntity entity) { Assert.notNull(parameterSource, "MapSqlParameterSource must not be null!"); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index fe989afd0d..9576affeb7 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -16,14 +16,18 @@ package org.springframework.data.jdbc.repository.support; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; +import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.JdbcAggregateOperations; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.FluentQuery; +import org.springframework.data.repository.query.QueryByExampleExecutor; import org.springframework.data.util.Streamable; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; @@ -34,14 +38,15 @@ * @author Jens Schauder * @author Oliver Gierke * @author Milan Milanov + * @author Diego Krupitza */ @Transactional(readOnly = true) -public class SimpleJdbcRepository implements PagingAndSortingRepository { +public class SimpleJdbcRepository implements PagingAndSortingRepository, QueryByExampleExecutor { private final JdbcAggregateOperations entityOperations; private final PersistentEntity entity; - public SimpleJdbcRepository(JdbcAggregateOperations entityOperations,PersistentEntity entity) { + public SimpleJdbcRepository(JdbcAggregateOperations entityOperations, PersistentEntity entity) { Assert.notNull(entityOperations, "EntityOperations must not be null."); Assert.notNull(entity, "Entity must not be null."); @@ -186,4 +191,67 @@ public Page findAll(Pageable pageable) { return entityOperations.findAll(entity.getType(), pageable); } + @Override + public Optional findOne(Example example) { + Assert.notNull(example, "Example must not be null!"); + return this.entityOperations.selectOne(example); + } + + @Override + public Iterable findAll(Example example) { + Assert.notNull(example, "Example must not be null!"); + + return findAll(example, Sort.unsorted()); + } + + @Override + public Iterable findAll(Example example, Sort sort) { + /*Assert.notNull(example, "Example must not be null!"); + Assert.notNull(sort, "Sort must not be null!"); + + Query query = this.exampleMapper.getMappedExample(example).sort(sort); + + return this.entityOperations.select(query, example.getProbeType());*/ + // TODO: impl + return null; + } + + @Override + public Page findAll(Example example, Pageable pageable) { + // TODO: impl + return null; + } + + @Override + public long count(Example example) { + /*Assert.notNull(example, "Example must not be null!"); + + Query query = this.exampleMapper.getMappedExample(example); + + return this.entityOperations.count(query, example.getProbeType());*/ + // TODO: impl + return 0; + } + + @Override + public boolean exists(Example example) { + + /*Assert.notNull(example, "Example must not be null!"); + + Query query = this.exampleMapper.getMappedExample(example); + + return this.entityOperations.exists(query, example.getProbeType());*/ + // TODO: impl + return false; + } + + @Override + public R findBy(Example example, Function, R> queryFunction) { + Assert.notNull(example, "Sample must not be null!"); + Assert.notNull(queryFunction, "Query function must not be null!"); + + // TODO: impl + + return null; + } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 85f9e1e1f7..db794eb813 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,7 +45,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.io.ClassPathResource; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.annotation.Id; +import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -66,6 +69,7 @@ import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; import org.springframework.data.repository.query.Param; +import org.springframework.data.repository.query.QueryByExampleExecutor; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; @@ -80,6 +84,7 @@ * * @author Jens Schauder * @author Mark Paluch + * @author Diego Krupitza */ @Transactional @TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS) @@ -575,6 +580,58 @@ void nullStringResult() { assertThat(repository.returnInput(null)).isNull(); } + @Test + void findOneByExampleShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + dummyEntity2.setName("Diego"); + + repository.save(dummyEntity2); + + Example diegoExample = Example.of(new DummyEntity("Diego")); + + Optional foundExampleDiego = repository.findOne(diegoExample); + + assertThat(foundExampleDiego).isPresent(); + assertThat(foundExampleDiego.get()).isNotNull(); + assertThat(foundExampleDiego.get().getName()).isEqualTo("Diego"); + } + + @Test + void findOneByExampleMultipleMatchShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(new DummyEntity()); + + assertThatThrownBy(() -> repository.findOne(example)).isInstanceOf(IncorrectResultSizeDataAccessException.class) + .hasMessageContaining("expected 1, actual 2"); + } + + @Test + void findOneByExampleShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + Example diegoExample = Example.of(new DummyEntity("NotExisting")); + + Optional foundExampleDiego = repository.findOne(diegoExample); + + assertThat(foundExampleDiego).isNotPresent(); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); @@ -598,7 +655,7 @@ private Instant createDummyBeforeAndAfterNow() { return now; } - interface DummyEntityRepository extends CrudRepository { + interface DummyEntityRepository extends CrudRepository, QueryByExampleExecutor { @Lock(LockMode.PESSIMISTIC_WRITE) List findAllByName(String name); From 1156e70d7a00fc421e30451697e5f57655e16e54 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Fri, 11 Mar 2022 17:00:30 +0100 Subject: [PATCH 45/51] Support of `QueryByExampleExecutor#findAll(...)`. This commit introduces the find by example method `findAll(...)` to spring-data-jdbc. MyBatis implementation is missing since I do not have the knowledge for this. Related tickets #1192 --- .../jdbc/core/JdbcAggregateOperations.java | 10 +++ .../data/jdbc/core/JdbcAggregateTemplate.java | 7 +++ .../convert/CascadingDataAccessStrategy.java | 5 ++ .../jdbc/core/convert/DataAccessStrategy.java | 9 +++ .../convert/DefaultDataAccessStrategy.java | 10 ++- .../convert/DelegatingDataAccessStrategy.java | 5 ++ .../data/jdbc/core/convert/SqlGenerator.java | 18 +++--- .../mybatis/MyBatisDataAccessStrategy.java | 7 +++ .../support/SimpleJdbcRepository.java | 10 +-- .../core/convert/SqlGeneratorUnitTests.java | 36 +++++++++-- .../JdbcRepositoryIntegrationTests.java | 63 ++++++++++++++++++- 11 files changed, 156 insertions(+), 24 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index a65146120b..c9b5206d4e 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -167,4 +167,14 @@ public interface JdbcAggregateOperations { * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ Optional selectOne(Example example); + + /** + * Execute a {@code SELECT} query and convert the resulting items to a {@link Iterable} that is sorted. + * + * @param example must not be null + * @param sort the sorting that should be used on the result. + * @return a non-null sorted list with all the matching results. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + Iterable select(Example example, Sort sort); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index 1ec9d49713..8a4aa07c0b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -270,6 +270,13 @@ public Optional selectOne(Example example) { return accessStrategy.selectOne(query, probeType); } + @Override public Iterable select(Example example, Sort sort) { + Query query = this.exampleMapper.getMappedExample(example).sort(sort); + Class probeType = example.getProbeType(); + + return accessStrategy.select(query, probeType); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.JdbcAggregateOperations#findAll(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java index 34b5aa0f8f..442cb682ef 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java @@ -216,6 +216,11 @@ public Optional selectOne(Query query, Class probeType) { return collect(das -> das.selectOne(query, probeType)); } + @Override + public Iterable select(Query query, Class probeType) { + return collect(das -> das.select(query, probeType)); + } + private T collect(Function function) { // Keep as Eclipse fails to compile if <> is used. diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java index 509e8bce2e..2b87b598d4 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java @@ -239,4 +239,13 @@ Iterable findAllByPath(Identifier identifier, * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ Optional selectOne(Query query, Class probeType); + + /** + * Execute a {@code SELECT} query and convert the resulting items to a {@link Iterable}. + * + * @param query must not be {@literal null}. + * @return a non null list with all the matching results. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + Iterable select(Query query, Class probeType); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index a4b879a727..79049fc360 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -437,7 +437,7 @@ public Iterable findAll(Class domainType, Pageable pageable) { @Override public Optional selectOne(Query query, Class probeType) { MapSqlParameterSource parameterSource = new MapSqlParameterSource(); - String sqlQuery = sql(probeType).selectOne(query, parameterSource); + String sqlQuery = sql(probeType).selectByQuery(query, parameterSource); T foundObject; try { @@ -449,6 +449,14 @@ public Optional selectOne(Query query, Class probeType) { return Optional.ofNullable(foundObject); } + @Override + public Iterable select(Query query, Class probeType) { + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + String sqlQuery = sql(probeType).selectByQuery(query, parameterSource); + + return operations.query(sqlQuery, parameterSource, (RowMapper) getEntityRowMapper(probeType)); + } + private SqlIdentifierParameterSource getParameterSource(@Nullable S instance, RelationalPersistentEntity persistentEntity, String prefix, Predicate skipProperty, IdentifierProcessing identifierProcessing) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java index 94105c2950..34c960c454 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java @@ -212,6 +212,11 @@ public Optional selectOne(Query query, Class probeType) { return delegate.selectOne(query, probeType); } + @Override + public Iterable select(Query query, Class probeType) { + return delegate.select(query, probeType); + } + /** * Must be called exactly once before calling any of the other methods. * diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index 7431cc3b26..bf9a6a9dbb 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -733,7 +733,7 @@ private OrderByField orderToOrderByField(Sort.Order order) { * @param parameterSource the source for holding the bindings * @return a non null query string. */ - public String selectOne(Query query, MapSqlParameterSource parameterSource) { + public String selectByQuery(Query query, MapSqlParameterSource parameterSource) { Assert.notNull(parameterSource, "parameterSource must not be null"); @@ -811,12 +811,12 @@ Column getParentId() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; Join join = (Join) o; - return joinTable.equals(join.joinTable) && - joinColumn.equals(join.joinColumn) && - parentId.equals(join.parentId); + return joinTable.equals(join.joinTable) && joinColumn.equals(join.joinColumn) && parentId.equals(join.parentId); } @Override @@ -827,11 +827,7 @@ public int hashCode() { @Override public String toString() { - return "Join{" + - "joinTable=" + joinTable + - ", joinColumn=" + joinColumn + - ", parentId=" + parentId + - '}'; + return "Join{" + "joinTable=" + joinTable + ", joinColumn=" + joinColumn + ", parentId=" + parentId + '}'; } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index c94118d654..53a790bd03 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -374,6 +374,13 @@ public Optional selectOne(Query query, Class probeType) { return Optional.empty(); } + @Override + public Iterable select(Query query, Class probeType) { + // TODO: DIEGO find help for this one + // I have zero MyBatis knowledge. + return null; + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.DataAccessStrategy#count(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index 9576affeb7..d4bdc54d67 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -206,14 +206,10 @@ public Iterable findAll(Example example) { @Override public Iterable findAll(Example example, Sort sort) { - /*Assert.notNull(example, "Example must not be null!"); + Assert.notNull(example, "Example must not be null!"); Assert.notNull(sort, "Sort must not be null!"); - - Query query = this.exampleMapper.getMappedExample(example).sort(sort); - - return this.entityOperations.select(query, example.getProbeType());*/ - // TODO: impl - return null; + + return this.entityOperations.select(example,sort); } @Override diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index 7ea24dfebe..5e097b881f 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -28,6 +28,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Version; +import org.springframework.data.domain.Example; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -46,10 +47,13 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Criteria; +import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.Aliased; import org.springframework.data.relational.core.sql.LockMode; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.core.sql.Table; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; /** * Unit tests for the {@link SqlGenerator}. @@ -64,6 +68,7 @@ * @author Myeonghyeon Lee * @author Mikhail Polivakha * @author Chirag Tailor + * @author Diego Krupitza */ class SqlGeneratorUnitTests { @@ -250,7 +255,8 @@ void findAllSortedWithNullHandling_resolvesNullHandlingWhenDialectSupportsIt() { SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, PostgresDialect.INSTANCE); - String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); + String sql = sqlGenerator + .getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); assertThat(sql).contains("ORDER BY \"dummy_entity\".\"x_name\" ASC NULLS LAST"); } @@ -260,7 +266,8 @@ void findAllSortedWithNullHandling_ignoresNullHandlingWhenDialectDoesNotSupportI SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, SqlServerDialect.INSTANCE); - String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); + String sql = sqlGenerator + .getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST))); assertThat(sql).endsWith("ORDER BY dummy_entity.x_name ASC"); } @@ -716,6 +723,25 @@ void columnForReferencedEntityWithoutId() { SqlIdentifier.quoted("child"), SqlIdentifier.quoted("CHILD_PARENT_OF_NO_ID_CHILD")); } + @Test + void selectByQueryValidTest() { + final SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class); + + DummyEntity probe = new DummyEntity(); + probe.name = "Diego"; + + Criteria criteria = Criteria.where("name").is(probe.name); + Query query = Query.query(criteria); + + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + + String generatedSQL = sqlGenerator.selectByQuery(query, parameterSource); + assertThat(generatedSQL).isNotNull().contains(":x_name"); + + assertThat(parameterSource.getValues()) // + .containsOnly(entry("x_name", probe.name)); + } + private SqlIdentifier getAlias(Object maybeAliased) { if (maybeAliased instanceof Aliased) { @@ -737,7 +763,8 @@ private PersistentPropertyPath getPath(String path @SuppressWarnings("unused") static class DummyEntity { - @Column("id1") @Id Long id; + @Column("id1") + @Id Long id; String name; ReferencedEntity ref; Set elements; @@ -810,7 +837,8 @@ static class EntityWithQuotedColumnName { // these column names behave like single double quote in the name since the get quoted and then doubling the double // quote escapes it. - @Id @Column("test\"\"_@id") Long id; + @Id + @Column("test\"\"_@id") Long id; @Column("test\"\"_@123") String name; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index db794eb813..51f630020f 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -611,7 +611,7 @@ void findOneByExampleMultipleMatchShouldGetOne() { DummyEntity dummyEntity2 = createDummyEntity(); repository.save(dummyEntity2); - Example example = Example.of(new DummyEntity()); + Example example = Example.of(createDummyEntity()); assertThatThrownBy(() -> repository.findOne(example)).isInstanceOf(IncorrectResultSizeDataAccessException.class) .hasMessageContaining("expected 1, actual 2"); @@ -632,6 +632,67 @@ void findOneByExampleShouldGetNone() { assertThat(foundExampleDiego).isNotPresent(); } + @Test + void findAllByExampleShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + dummyEntity2.setName("Diego"); + + repository.save(dummyEntity2); + + Example example = Example.of(new DummyEntity("Diego")); + + Iterable allFound = repository.findAll(example); + + assertThat(allFound) // + .isNotNull() // + .hasSize(1) // + .extracting(DummyEntity::getName) // + .containsExactly(example.getProbe().getName()); + } + + @Test + void findAllByExampleMultipleMatchShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(createDummyEntity()); + + Iterable allFound = repository.findAll(example); + + assertThat(allFound) // + .isNotNull() // + .hasSize(2) // + .extracting(DummyEntity::getName) // + .containsOnly(example.getProbe().getName()); + } + + @Test + void findAllByExampleShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + Example example = Example.of(new DummyEntity("NotExisting")); + + Iterable allFound = repository.findAll(example); + + assertThat(allFound) // + .isNotNull() // + .isEmpty(); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); From 03088ef83ea1e9114df724940eea4fa93ce79444 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Fri, 11 Mar 2022 20:53:33 +0100 Subject: [PATCH 46/51] Support of `QueryByExampleExecutor#exists(...)`. This commit introduces the exists by example method `exists(...)` to spring-data-jdbc. MyBatis implementation is missing since I do not have the knowledge for this. Related tickets #1192 --- .../jdbc/core/JdbcAggregateOperations.java | 8 +++ .../data/jdbc/core/JdbcAggregateTemplate.java | 12 +++- .../convert/CascadingDataAccessStrategy.java | 5 ++ .../jdbc/core/convert/DataAccessStrategy.java | 12 +++- .../convert/DefaultDataAccessStrategy.java | 12 ++++ .../convert/DelegatingDataAccessStrategy.java | 5 ++ .../data/jdbc/core/convert/SqlGenerator.java | 56 ++++++++++++--- .../mybatis/MyBatisDataAccessStrategy.java | 6 ++ .../support/SimpleJdbcRepository.java | 11 +-- .../core/convert/SqlGeneratorUnitTests.java | 19 +++++ .../JdbcRepositoryIntegrationTests.java | 72 +++++++++++++++++++ 11 files changed, 200 insertions(+), 18 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index c9b5206d4e..3c64c4ac33 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -177,4 +177,12 @@ public interface JdbcAggregateOperations { * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ Iterable select(Example example, Sort sort); + + /** + * Determine whether the result matches {@link Example} + * + * @param example must not be {@literal null}. + * @return {@literal true} if the object exists. + */ + boolean exists(Example example); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index 8a4aa07c0b..e6c67170b0 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -270,13 +270,23 @@ public Optional selectOne(Example example) { return accessStrategy.selectOne(query, probeType); } - @Override public Iterable select(Example example, Sort sort) { + @Override + public Iterable select(Example example, Sort sort) { Query query = this.exampleMapper.getMappedExample(example).sort(sort); Class probeType = example.getProbeType(); return accessStrategy.select(query, probeType); } + @Override + public boolean exists(Example example) { + Query query = this.exampleMapper.getMappedExample(example); + + Class probeType = example.getProbeType(); + + return accessStrategy.exists(query, probeType); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.JdbcAggregateOperations#findAll(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java index 442cb682ef..a582bbc3b7 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java @@ -221,6 +221,11 @@ public Iterable select(Query query, Class probeType) { return collect(das -> das.select(query, probeType)); } + @Override + public boolean exists(Query query, Class probeType) { + return collect(das -> das.exists(query, probeType)); + } + private T collect(Function function) { // Keep as Eclipse fails to compile if <> is used. diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java index 2b87b598d4..10a6170a3d 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java @@ -18,7 +18,6 @@ import java.util.Map; import java.util.Optional; -import org.springframework.dao.DataAccessException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -235,6 +234,7 @@ Iterable findAllByPath(Identifier identifier, * Execute a {@code SELECT} query and convert the resulting item to an entity ensuring exactly one result. * * @param query must not be {@literal null}. + * @param probeType the type of entities. Must not be {@code null}. * @return exactly one result or {@link Optional#empty()} if no match found. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ @@ -244,8 +244,18 @@ Iterable findAllByPath(Identifier identifier, * Execute a {@code SELECT} query and convert the resulting items to a {@link Iterable}. * * @param query must not be {@literal null}. + * @param probeType the type of entities. Must not be {@code null}. * @return a non null list with all the matching results. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ Iterable select(Query query, Class probeType); + + /** + * Determine whether there is an aggregate of type probeType that matches the provided {@link Query}. + * + * @param query must not be {@literal null}. + * @param probeType the type of entities. Must not be {@code null}. + * @return {@literal true} if the object exists. + */ + boolean exists(Query query, Class probeType); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index 79049fc360..b8b50fc82b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -457,6 +457,18 @@ public Iterable select(Query query, Class probeType) { return operations.query(sqlQuery, parameterSource, (RowMapper) getEntityRowMapper(probeType)); } + @Override + public boolean exists(Query query, Class probeType) { + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + + String sqlQuery = sql(probeType).existsByQuery(query, parameterSource); + + Boolean result = operations.queryForObject(sqlQuery, parameterSource, Boolean.class); + Assert.notNull(result, "The result of an exists query must not be null"); + + return result; + } + private SqlIdentifierParameterSource getParameterSource(@Nullable S instance, RelationalPersistentEntity persistentEntity, String prefix, Predicate skipProperty, IdentifierProcessing identifierProcessing) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java index 34c960c454..2239a07bcf 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java @@ -217,6 +217,11 @@ public Iterable select(Query query, Class probeType) { return delegate.select(query, probeType); } + @Override + public boolean exists(Query query, Class probeType) { + return delegate.exists(query, probeType); + } + /** * Must be called exactly once before calling any of the other methods. * diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index bf9a6a9dbb..85ace19686 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -737,10 +737,55 @@ public String selectByQuery(Query query, MapSqlParameterSource parameterSource) Assert.notNull(parameterSource, "parameterSource must not be null"); - Table table = Table.create(this.entity.getTableName()); - SelectBuilder.SelectWhere selectBuilder = selectBuilder(); + Select select = applyQueryOnSelect(query, parameterSource, selectBuilder) // + .build(); + + return render(select); + } + + /** + * Constructs a single sql query that performs select count based on the provided query. Additional the bindings for + * the where clause are stored after execution into the parameterSource + * + * @param query the query to base the select on. Must not be null + * @param parameterSource the source for holding the bindings + * @return a non null query string. + */ + public String existsByQuery(Query query, MapSqlParameterSource parameterSource) { + Table table = getTable(); + + SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder // + .select(Functions.count(getIdColumn())) // + .from(table);// + + SelectBuilder.SelectJoin baseSelect = selectBuilder; + + // add possible joins + for (PersistentPropertyPath path : mappingContext + .findPersistentPropertyPaths(entity.getType(), p -> true)) { + + PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(mappingContext, path); + + // add a join if necessary + Join join = getJoin(extPath); + if (join != null) { + baseSelect = baseSelect.leftOuterJoin(join.joinTable).on(join.joinColumn).equals(join.parentId); + } + } + + Select select = applyQueryOnSelect(query, parameterSource, (SelectBuilder.SelectWhere) baseSelect) // + .build(); + + return render(select); + } + + private SelectBuilder.SelectOrdered applyQueryOnSelect(Query query, MapSqlParameterSource parameterSource, + SelectBuilder.SelectWhere selectBuilder) { + + Table table = Table.create(this.entity.getTableName()); + SelectBuilder.SelectOrdered selectOrdered = query // .getCriteria() // .map(item -> this.applyCriteria(item, selectBuilder, parameterSource, table)) // @@ -760,12 +805,7 @@ public String selectByQuery(Query query, MapSqlParameterSource parameterSource) if (query.getOffset() > 0) { limitable = limitable.offset(query.getOffset()); } - - selectOrdered = (SelectBuilder.SelectOrdered) limitable; - Select select = selectOrdered // - .build(); - - return render(select); + return (SelectBuilder.SelectOrdered) limitable; } SelectBuilder.SelectOrdered applyCriteria(@Nullable CriteriaDefinition criteria, diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index 53a790bd03..0903cf4ef7 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -381,6 +381,12 @@ public Iterable select(Query query, Class probeType) { return null; } + @Override public boolean exists(Query query, Class probeType) { + // TODO: DIEGO find help for this one + // I have zero MyBatis knowledge. + return false; + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.DataAccessStrategy#count(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index d4bdc54d67..c57564fd2d 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -209,7 +209,7 @@ public Iterable findAll(Example example, Sort sort) { Assert.notNull(example, "Example must not be null!"); Assert.notNull(sort, "Sort must not be null!"); - return this.entityOperations.select(example,sort); + return this.entityOperations.select(example, sort); } @Override @@ -231,14 +231,9 @@ public long count(Example example) { @Override public boolean exists(Example example) { + Assert.notNull(example, "Example must not be null!"); - /*Assert.notNull(example, "Example must not be null!"); - - Query query = this.exampleMapper.getMappedExample(example); - - return this.entityOperations.exists(query, example.getProbeType());*/ - // TODO: impl - return false; + return this.entityOperations.exists(example); } @Override diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index 5e097b881f..754f70a191 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -742,6 +742,25 @@ void selectByQueryValidTest() { .containsOnly(entry("x_name", probe.name)); } + @Test + void existsByQuerySimpleValidTest() { + final SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class); + + DummyEntity probe = new DummyEntity(); + probe.name = "Diego"; + + Criteria criteria = Criteria.where("name").is(probe.name); + Query query = Query.query(criteria); + + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + + String generatedSQL = sqlGenerator.existsByQuery(query, parameterSource); + assertThat(generatedSQL).isNotNull().contains(":x_name"); + + assertThat(parameterSource.getValues()) // + .containsOnly(entry("x_name", probe.name)); + } + private SqlIdentifier getAlias(Object maybeAliased) { if (maybeAliased instanceof Aliased) { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 51f630020f..869f42f5ff 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -693,6 +693,78 @@ void findAllByExampleShouldGetNone() { .isEmpty(); } + @Test + void existsByExampleShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + dummyEntity2.setName("Diego"); + + repository.save(dummyEntity2); + + Example example = Example.of(new DummyEntity("Diego")); + + boolean exists = repository.exists(example); + + assertThat(exists).isTrue(); + } + + @Test + void existsByExampleMultipleMatchShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(createDummyEntity()); + + boolean exists = repository.exists(example); + assertThat(exists).isTrue(); + } + + @Test + void existsByExampleShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + Example example = Example.of(new DummyEntity("NotExisting")); + + boolean exists = repository.exists(example); + + assertThat(exists).isFalse(); + } + + @Test + void existsByExampleComplex() { + + final Instant pointInTime = Instant.now().minusSeconds(10000); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + two.setName("Diego"); + two.setPointInTime(pointInTime); + two = repository.save(two); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName("Diego"); + exampleEntitiy.setPointInTime(pointInTime); + + Example example = Example.of(exampleEntitiy); + + boolean exists = repository.exists(example); + assertThat(exists).isTrue(); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); From a9f653b57add99fe4a35a2a4bb7b0a8d20a2a256 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 12 Mar 2022 13:35:38 +0100 Subject: [PATCH 47/51] Support of `QueryByExampleExecutor#count(...)`. This commit introduces the count by example method `count(...)` to spring-data-jdbc. MyBatis implementation is missing since I do not have the knowledge for this. Related tickets #1192 --- .../jdbc/core/JdbcAggregateOperations.java | 8 +++ .../data/jdbc/core/JdbcAggregateTemplate.java | 7 ++ .../convert/CascadingDataAccessStrategy.java | 5 ++ .../jdbc/core/convert/DataAccessStrategy.java | 9 +++ .../convert/DefaultDataAccessStrategy.java | 12 ++++ .../convert/DelegatingDataAccessStrategy.java | 5 ++ .../data/jdbc/core/convert/SqlGenerator.java | 53 +++++++++++--- .../mybatis/MyBatisDataAccessStrategy.java | 10 ++- .../support/SimpleJdbcRepository.java | 10 +-- .../core/convert/SqlGeneratorUnitTests.java | 22 ++++++ .../JdbcRepositoryIntegrationTests.java | 72 +++++++++++++++++++ 11 files changed, 197 insertions(+), 16 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index 3c64c4ac33..3f83a4db09 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -185,4 +185,12 @@ public interface JdbcAggregateOperations { * @return {@literal true} if the object exists. */ boolean exists(Example example); + + /** + * Counts the number of aggregates of a given type that match the given example. + * + * @param example the example to match. + * @return the number of instances stored in the database. Guaranteed to be not {@code null}. + */ + long count(Example example); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index e6c67170b0..458ab8de1a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -287,6 +287,13 @@ public boolean exists(Example example) { return accessStrategy.exists(query, probeType); } + @Override + public long count(Example example) { + Query query = this.exampleMapper.getMappedExample(example); + Class probeType = example.getProbeType(); + return accessStrategy.count(query, probeType); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.JdbcAggregateOperations#findAll(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java index a582bbc3b7..944f2ab292 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java @@ -226,6 +226,11 @@ public boolean exists(Query query, Class probeType) { return collect(das -> das.exists(query, probeType)); } + @Override + public long count(Query query, Class probeType) { + return collect(das -> das.count(query, probeType)); + } + private T collect(Function function) { // Keep as Eclipse fails to compile if <> is used. diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java index 10a6170a3d..a611005713 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java @@ -258,4 +258,13 @@ Iterable findAllByPath(Identifier identifier, * @return {@literal true} if the object exists. */ boolean exists(Query query, Class probeType); + + /** + * Counts the rows in the table representing the given probe type, that match the given query. + * + * @param probeType the probe type for which to count the elements. Must not be {@code null}. + * @param query the query which elements have to match. + * @return the count. Guaranteed to be not {@code null}. + */ + long count(Query query, Class probeType); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index b8b50fc82b..aa644a10dc 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -469,6 +469,18 @@ public boolean exists(Query query, Class probeType) { return result; } + @Override + public long count(Query query, Class probeType) { + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + String sqlQuery = sql(probeType).countByQuery(query, parameterSource); + + Long result = operations.queryForObject(sqlQuery, parameterSource, Long.class); + + Assert.notNull(result, "The result of a count query must not be null."); + + return result; + } + private SqlIdentifierParameterSource getParameterSource(@Nullable S instance, RelationalPersistentEntity persistentEntity, String prefix, Predicate skipProperty, IdentifierProcessing identifierProcessing) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java index 2239a07bcf..f188bad53c 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java @@ -222,6 +222,11 @@ public boolean exists(Query query, Class probeType) { return delegate.exists(query, probeType); } + @Override + public long count(Query query, Class probeType) { + return delegate.count(query, probeType); + } + /** * Must be called exactly once before calling any of the other methods. * diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index 85ace19686..3692d2b0d5 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -745,6 +745,25 @@ public String selectByQuery(Query query, MapSqlParameterSource parameterSource) return render(select); } + /** + * Constructs a single sql query that performs select count based on the provided query for checking existence. + * Additional the bindings for the where clause are stored after execution into the parameterSource + * + * @param query the query to base the select on. Must not be null + * @param parameterSource the source for holding the bindings + * @return a non null query string. + */ + public String existsByQuery(Query query, MapSqlParameterSource parameterSource) { + + Expression idColumn = getIdColumn(); + SelectBuilder.SelectJoin baseSelect = getSelectCountWithExpression(idColumn); + + Select select = applyQueryOnSelect(query, parameterSource, (SelectBuilder.SelectWhere) baseSelect) // + .build(); + + return render(select); + } + /** * Constructs a single sql query that performs select count based on the provided query. Additional the bindings for * the where clause are stored after execution into the parameterSource @@ -753,11 +772,33 @@ public String selectByQuery(Query query, MapSqlParameterSource parameterSource) * @param parameterSource the source for holding the bindings * @return a non null query string. */ - public String existsByQuery(Query query, MapSqlParameterSource parameterSource) { - Table table = getTable(); + public String countByQuery(Query query, MapSqlParameterSource parameterSource) { + + Expression countExpression = Expressions.just("1"); + SelectBuilder.SelectJoin baseSelect = getSelectCountWithExpression(countExpression); + Select select = applyQueryOnSelect(query, parameterSource, (SelectBuilder.SelectWhere) baseSelect) // + .build(); + + return render(select); + } + + /** + * Generates a {@link org.springframework.data.relational.core.sql.SelectBuilder.SelectJoin} with a + * COUNT(...) where the countExpressions are the parameters of the count. + * + * @param countExpressions the expression to use as count parameter. + * @return a non-null {@link org.springframework.data.relational.core.sql.SelectBuilder.SelectJoin} that joins all the + * columns and has only a count in the projection of the select. + */ + private SelectBuilder.SelectJoin getSelectCountWithExpression(Expression... countExpressions) { + + Assert.notNull(countExpressions, "countExpressions must not be null"); + Assert.state(countExpressions.length >= 1, "countExpressions must contain at least one expression"); + + Table table = getTable(); SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder // - .select(Functions.count(getIdColumn())) // + .select(Functions.count(countExpressions)) // .from(table);// SelectBuilder.SelectJoin baseSelect = selectBuilder; @@ -774,11 +815,7 @@ public String existsByQuery(Query query, MapSqlParameterSource parameterSource) baseSelect = baseSelect.leftOuterJoin(join.joinTable).on(join.joinColumn).equals(join.parentId); } } - - Select select = applyQueryOnSelect(query, parameterSource, (SelectBuilder.SelectWhere) baseSelect) // - .build(); - - return render(select); + return baseSelect; } private SelectBuilder.SelectOrdered applyQueryOnSelect(Query query, MapSqlParameterSource parameterSource, diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index 0903cf4ef7..acce072104 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -381,12 +381,20 @@ public Iterable select(Query query, Class probeType) { return null; } - @Override public boolean exists(Query query, Class probeType) { + @Override + public boolean exists(Query query, Class probeType) { // TODO: DIEGO find help for this one // I have zero MyBatis knowledge. return false; } + @Override + public long count(Query query, Class probeType) { + // TODO: DIEGO find help for this one + // I have zero MyBatis knowledge. + return 0; + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.DataAccessStrategy#count(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index c57564fd2d..ddaeaea183 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -220,13 +220,9 @@ public Page findAll(Example example, Pageable pageable) { @Override public long count(Example example) { - /*Assert.notNull(example, "Example must not be null!"); - - Query query = this.exampleMapper.getMappedExample(example); - - return this.entityOperations.count(query, example.getProbeType());*/ - // TODO: impl - return 0; + Assert.notNull(example, "Example must not be null!"); + + return this.entityOperations.count(example); } @Override diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index 754f70a191..229626958c 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -761,6 +761,28 @@ void existsByQuerySimpleValidTest() { .containsOnly(entry("x_name", probe.name)); } + @Test + void countByQuerySimpleValidTest() { + final SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class); + + DummyEntity probe = new DummyEntity(); + probe.name = "Diego"; + + Criteria criteria = Criteria.where("name").is(probe.name); + Query query = Query.query(criteria); + + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + + String generatedSQL = sqlGenerator.countByQuery(query, parameterSource); + assertThat(generatedSQL) // + .isNotNull() // + .containsIgnoringCase("COUNT(1)") // + .contains(":x_name"); + + assertThat(parameterSource.getValues()) // + .containsOnly(entry("x_name", probe.name)); + } + private SqlIdentifier getAlias(Object maybeAliased) { if (maybeAliased instanceof Aliased) { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 869f42f5ff..4ffef12740 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -765,6 +765,78 @@ void existsByExampleComplex() { assertThat(exists).isTrue(); } + @Test + void countByExampleShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + dummyEntity2.setName("Diego"); + + repository.save(dummyEntity2); + + Example example = Example.of(new DummyEntity("Diego")); + + long count = repository.count(example); + + assertThat(count).isOne(); + } + + @Test + void countByExampleMultipleMatchShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(createDummyEntity()); + + long count = repository.count(example); + assertThat(count).isEqualTo(2); + } + + @Test + void countByExampleShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + Example example = Example.of(new DummyEntity("NotExisting")); + + long count = repository.count(example); + + assertThat(count).isNotNull().isZero(); + } + + @Test + void countByExampleComplex() { + + final Instant pointInTime = Instant.now().minusSeconds(10000); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + two.setName("Diego"); + two.setPointInTime(pointInTime); + two = repository.save(two); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName("Diego"); + exampleEntitiy.setPointInTime(pointInTime); + + Example example = Example.of(exampleEntitiy); + + long count = repository.count(example); + assertThat(count).isOne(); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); From 239a720662bcff92638dea1cf49e3d23aeb8cd12 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 12 Mar 2022 19:02:31 +0100 Subject: [PATCH 48/51] Support of `QueryByExampleExecutor#findAll(Example example, Pageable pageable)`. This commit introduces the find by example pageable method `findAll(Example example, Pageable pageable)` to spring-data-jdbc. MyBatis implementation is missing since I do not have the knowledge for this. Related tickets #1192 --- .../jdbc/core/JdbcAggregateOperations.java | 10 ++ .../data/jdbc/core/JdbcAggregateTemplate.java | 11 ++ .../convert/CascadingDataAccessStrategy.java | 5 + .../jdbc/core/convert/DataAccessStrategy.java | 14 +- .../convert/DefaultDataAccessStrategy.java | 8 + .../convert/DelegatingDataAccessStrategy.java | 5 + .../data/jdbc/core/convert/SqlGenerator.java | 25 ++++ .../mybatis/MyBatisDataAccessStrategy.java | 11 +- .../support/SimpleJdbcRepository.java | 5 +- .../core/convert/SqlGeneratorUnitTests.java | 27 +++- .../JdbcRepositoryIntegrationTests.java | 139 +++++++++++++++++- 11 files changed, 253 insertions(+), 7 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index 3f83a4db09..d893e35f7b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -193,4 +193,14 @@ public interface JdbcAggregateOperations { * @return the number of instances stored in the database. Guaranteed to be not {@code null}. */ long count(Example example); + + /** + * Returns a {@link Page} of entities matching the given {@link Example}. In case no match could be found, an empty + * {@link Page} is returned. + * + * @param example must not be null + * @param pageable can be null. + * @return a {@link Page} of entities matching the given {@link Example}. + */ + Page select(Example example, Pageable pageable); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index 458ab8de1a..b17e8fb176 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -294,6 +294,17 @@ public long count(Example example) { return accessStrategy.count(query, probeType); } + @Override + public Page select(Example example, Pageable pageable) { + Query query = this.exampleMapper.getMappedExample(example); + Class probeType = example.getProbeType(); + + Iterable items = triggerAfterConvert(accessStrategy.select(query, probeType, pageable)); + List content = StreamSupport.stream(items.spliterator(), false).collect(Collectors.toList()); + + return PageableExecutionUtils.getPage(content, pageable, () -> accessStrategy.count(query, probeType)); + } + /* * (non-Javadoc) * @see org.springframework.data.jdbc.core.JdbcAggregateOperations#findAll(java.lang.Class) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java index 944f2ab292..d0d7fd4fdc 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java @@ -221,6 +221,11 @@ public Iterable select(Query query, Class probeType) { return collect(das -> das.select(query, probeType)); } + @Override + public Iterable select(Query query, Class probeType, Pageable pageable) { + return collect(das -> das.select(query, probeType, pageable)); + } + @Override public boolean exists(Query query, Class probeType) { return collect(das -> das.exists(query, probeType)); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java index a611005713..1274d14dfa 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategy.java @@ -245,11 +245,23 @@ Iterable findAllByPath(Identifier identifier, * * @param query must not be {@literal null}. * @param probeType the type of entities. Must not be {@code null}. - * @return a non null list with all the matching results. + * @return a non-null list with all the matching results. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ Iterable select(Query query, Class probeType); + /** + * Execute a {@code SELECT} query and convert the resulting items to a {@link Iterable}. Applies the {@link Pageable} + * to the result. + * + * @param query must not be {@literal null}. + * @param probeType the type of entities. Must not be {@literal null}. + * @param pageable the pagination that should be applied. Must not be {@literal null}. + * @return a non-null list with all the matching results. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + Iterable select(Query query, Class probeType, Pageable pageable); + /** * Determine whether there is an aggregate of type probeType that matches the provided {@link Query}. * diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index aa644a10dc..28e2347730 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -457,6 +457,14 @@ public Iterable select(Query query, Class probeType) { return operations.query(sqlQuery, parameterSource, (RowMapper) getEntityRowMapper(probeType)); } + @Override + public Iterable select(Query query, Class probeType, Pageable pageable) { + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + String sqlQuery = sql(probeType).selectByQuery(query, parameterSource, pageable); + + return operations.query(sqlQuery, parameterSource, (RowMapper) getEntityRowMapper(probeType)); + } + @Override public boolean exists(Query query, Class probeType) { MapSqlParameterSource parameterSource = new MapSqlParameterSource(); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java index f188bad53c..6ae4e7319f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java @@ -217,6 +217,11 @@ public Iterable select(Query query, Class probeType) { return delegate.select(query, probeType); } + @Override + public Iterable select(Query query, Class probeType, Pageable pageable) { + return delegate.select(query, probeType, pageable); + } + @Override public boolean exists(Query query, Class probeType) { return delegate.exists(query, probeType); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index 3692d2b0d5..ede6b2e906 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -745,6 +745,31 @@ public String selectByQuery(Query query, MapSqlParameterSource parameterSource) return render(select); } + /** + * Constructs a single sql query that performs select based on the provided query and pagination information. + * Additional the bindings for the where clause are stored after execution into the parameterSource + * + * @param query the query to base the select on. Must not be null. + * @param pageable the pageable to perform on the select. + * @param parameterSource the source for holding the bindings. + * @return a non null query string. + */ + public String selectByQuery(Query query, MapSqlParameterSource parameterSource, Pageable pageable) { + + Assert.notNull(parameterSource, "parameterSource must not be null"); + + SelectBuilder.SelectWhere selectBuilder = selectBuilder(); + + // first apply query and then pagination. This means possible query sorting and limiting might be overwritten by the + // pagination. This is desired. + SelectBuilder.SelectOrdered selectOrdered = applyQueryOnSelect(query, parameterSource, selectBuilder); + selectOrdered = applyPagination(pageable, selectOrdered); + selectOrdered = selectOrdered.orderBy(extractOrderByFields(pageable.getSort())); + + Select select = selectOrdered.build(); + return render(select); + } + /** * Constructs a single sql query that performs select count based on the provided query for checking existence. * Additional the bindings for the where clause are stored after execution into the parameterSource diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index acce072104..561683aa60 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -23,10 +23,10 @@ import java.util.Optional; import java.util.stream.Collectors; -import org.apache.ibatis.session.SqlSession; -import org.mybatis.spring.SqlSessionTemplate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ibatis.session.SqlSession; +import org.mybatis.spring.SqlSessionTemplate; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -381,6 +381,13 @@ public Iterable select(Query query, Class probeType) { return null; } + @Override + public Iterable select(Query query, Class probeType, Pageable pageable) { + // TODO: DIEGO find help for this one + // I have zero MyBatis knowledge. + return null; + } + @Override public boolean exists(Query query, Class probeType) { // TODO: DIEGO find help for this one diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index ddaeaea183..416251ab82 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -214,8 +214,9 @@ public Iterable findAll(Example example, Sort sort) { @Override public Page findAll(Example example, Pageable pageable) { - // TODO: impl - return null; + Assert.notNull(example, "Example must not be null!"); + + return this.entityOperations.select(example, pageable); } @Override diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index 229626958c..f3dd7e49f3 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -28,7 +28,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Version; -import org.springframework.data.domain.Example; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -783,6 +782,32 @@ void countByQuerySimpleValidTest() { .containsOnly(entry("x_name", probe.name)); } + @Test + void selectByQueryPaginationValidTest() { + final SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class); + + DummyEntity probe = new DummyEntity(); + probe.name = "Diego"; + + Criteria criteria = Criteria.where("name").is(probe.name); + Query query = Query.query(criteria); + + PageRequest pageRequest = PageRequest.of(2, 1, Sort.by(Sort.Order.asc("name"))); + + MapSqlParameterSource parameterSource = new MapSqlParameterSource(); + + String generatedSQL = sqlGenerator.selectByQuery(query, parameterSource, pageRequest); + assertThat(generatedSQL) // + .isNotNull() // + .contains(":x_name") // + .containsIgnoringCase("ORDER BY dummy_entity.x_name ASC") // + .containsIgnoringCase("LIMIT 1") // + .containsIgnoringCase("OFFSET 2 LIMIT 1"); + + assertThat(parameterSource.getValues()) // + .containsOnly(entry("x_name", probe.name)); + } + private SqlIdentifier getAlias(Object maybeAliased) { if (maybeAliased instanceof Aliased) { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 4ffef12740..1b8361b5b0 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -32,12 +32,17 @@ import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.ApplicationListener; @@ -53,7 +58,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jdbc.core.mapping.AggregateReference; -import org.springframework.data.relational.repository.Lock; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; @@ -65,6 +69,7 @@ import org.springframework.data.relational.core.mapping.event.AfterConvertEvent; import org.springframework.data.relational.core.mapping.event.AfterLoadEvent; import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; @@ -693,6 +698,138 @@ void findAllByExampleShouldGetNone() { .isEmpty(); } + @Test + void findAllByExamplePageableShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + dummyEntity2.setName("Diego"); + + repository.save(dummyEntity2); + + Example example = Example.of(new DummyEntity("Diego")); + Pageable pageRequest = PageRequest.of(0, 10); + + Iterable allFound = repository.findAll(example, pageRequest); + + assertThat(allFound) // + .isNotNull() // + .hasSize(1) // + .extracting(DummyEntity::getName) // + .containsExactly(example.getProbe().getName()); + } + + @Test + void findAllByExamplePageableMultipleMatchShouldGetOne() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(createDummyEntity()); + Pageable pageRequest = PageRequest.of(0, 10); + + Iterable allFound = repository.findAll(example, pageRequest); + + assertThat(allFound) // + .isNotNull() // + .hasSize(2) // + .extracting(DummyEntity::getName) // + .containsOnly(example.getProbe().getName()); + } + + @Test + void findAllByExamplePageableShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + dummyEntity1.setFlag(true); + + repository.save(dummyEntity1); + + Example example = Example.of(new DummyEntity("NotExisting")); + Pageable pageRequest = PageRequest.of(0, 10); + + Iterable allFound = repository.findAll(example, pageRequest); + + assertThat(allFound) // + .isNotNull() // + .isEmpty(); + } + + @Test + void findAllByExamplePageableOutsidePageShouldGetNone() { + + DummyEntity dummyEntity1 = createDummyEntity(); + repository.save(dummyEntity1); + + DummyEntity dummyEntity2 = createDummyEntity(); + repository.save(dummyEntity2); + + Example example = Example.of(createDummyEntity()); + Pageable pageRequest = PageRequest.of(10, 10); + + Iterable allFound = repository.findAll(example, pageRequest); + + assertThat(allFound) // + .isNotNull() // + .isEmpty(); + } + + @ParameterizedTest + @MethodSource("findAllByExamplePageableSource") + void findAllByExamplePageable(Pageable pageRequest, int size, int totalPages, List notContains) { + + for (int i = 0; i < 100; i++) { + DummyEntity dummyEntity = createDummyEntity(); + dummyEntity.setFlag(true); + dummyEntity.setName("" + i); + + repository.save(dummyEntity); + } + + DummyEntity dummyEntityExample = createDummyEntity(); + dummyEntityExample.setName(null); + dummyEntityExample.setFlag(true); + + Example example = Example.of(dummyEntityExample); + + Page allFound = repository.findAll(example, pageRequest); + + // page has correct size + assertThat(allFound) // + .isNotNull() // + .hasSize(size); + + // correct number of total + assertThat(allFound.getTotalElements()).isEqualTo(100); + + assertThat(allFound.getTotalPages()).isEqualTo(totalPages); + + if (!notContains.isEmpty()) { + assertThat(allFound) // + .extracting(DummyEntity::getName) // + .doesNotContain(notContains.toArray(new String[0])); + } + } + + public static Stream findAllByExamplePageableSource() { + return Stream.of( // + Arguments.of(PageRequest.of(0, 3), 3, 34, Arrays.asList("3", "4", "100")), // + Arguments.of(PageRequest.of(1, 10), 10, 10, Arrays.asList("9", "20", "30")), // + Arguments.of(PageRequest.of(2, 10), 10, 10, Arrays.asList("1", "2", "3")), // + Arguments.of(PageRequest.of(33, 3), 1, 34, Collections.emptyList()), // + Arguments.of(PageRequest.of(36, 3), 0, 34, Collections.emptyList()), // + Arguments.of(PageRequest.of(0, 10000), 100, 1, Collections.emptyList()), // + Arguments.of(PageRequest.of(100, 10000), 0, 1, Collections.emptyList()) // + ); + } + @Test void existsByExampleShouldGetOne() { From b878bbaa7638790145b3a5365fa7c68c9965c5ff Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 12 Mar 2022 19:52:04 +0100 Subject: [PATCH 49/51] Marked missing implementations with `UnsupportedOperationException`. Missing MyBatisDataAccessStrategy implementation and `findBy(Example example, Function, R> queryFunction)` marked with `UnsupportedOperationException`. Related tickets #1192 --- .../mybatis/MyBatisDataAccessStrategy.java | 20 +++++-------------- .../support/SimpleJdbcRepository.java | 7 +------ 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java index 561683aa60..387f00f988 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java @@ -369,37 +369,27 @@ public Iterable findAll(Class domainType, Pageable pageable) { @Override public Optional selectOne(Query query, Class probeType) { - // TODO: DIEGO find help for this one - // I have zero MyBatis knowledge. - return Optional.empty(); + throw new UnsupportedOperationException("Not implemented"); } @Override public Iterable select(Query query, Class probeType) { - // TODO: DIEGO find help for this one - // I have zero MyBatis knowledge. - return null; + throw new UnsupportedOperationException("Not implemented"); } @Override public Iterable select(Query query, Class probeType, Pageable pageable) { - // TODO: DIEGO find help for this one - // I have zero MyBatis knowledge. - return null; + throw new UnsupportedOperationException("Not implemented"); } @Override public boolean exists(Query query, Class probeType) { - // TODO: DIEGO find help for this one - // I have zero MyBatis knowledge. - return false; + throw new UnsupportedOperationException("Not implemented"); } @Override public long count(Query query, Class probeType) { - // TODO: DIEGO find help for this one - // I have zero MyBatis knowledge. - return 0; + throw new UnsupportedOperationException("Not implemented"); } /* diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index 416251ab82..bcc8f3d185 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -235,11 +235,6 @@ public boolean exists(Example example) { @Override public R findBy(Example example, Function, R> queryFunction) { - Assert.notNull(example, "Sample must not be null!"); - Assert.notNull(queryFunction, "Query function must not be null!"); - - // TODO: impl - - return null; + throw new UnsupportedOperationException("Not implemented"); } } From 62559f679c5da380269608eb2412ae5ade007924 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 9 Apr 2022 14:54:10 +0200 Subject: [PATCH 50/51] Removed `Example` abstraction from `JdbcAggregateTemplate`. --- .../jdbc/core/JdbcAggregateOperations.java | 34 ++++++++------- .../data/jdbc/core/JdbcAggregateTemplate.java | 42 +++++-------------- .../support/JdbcRepositoryFactory.java | 3 +- .../support/SimpleJdbcRepository.java | 20 +++++---- .../JdbcRepositoryIntegrationTests.java | 1 - ...nableJdbcRepositoriesIntegrationTests.java | 4 +- .../SimpleJdbcRepositoryUnitTests.java | 4 +- 7 files changed, 52 insertions(+), 56 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java index d893e35f7b..60f8f68a6a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java @@ -21,6 +21,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.relational.core.query.Query; import org.springframework.lang.Nullable; /** @@ -162,45 +163,50 @@ public interface JdbcAggregateOperations { /** * Execute a {@code SELECT} query and convert the resulting item to an entity ensuring exactly one result. * - * @param example must not be null + * @param query must not be {@literal null}. + * @param entityClass the entity type must not be {@literal null}. * @return exactly one result or {@link Optional#empty()} if no match found. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ - Optional selectOne(Example example); + Optional selectOne(Query query, Class entityClass); /** * Execute a {@code SELECT} query and convert the resulting items to a {@link Iterable} that is sorted. * - * @param example must not be null + * @param query must not be {@literal null}. + * @param entityClass the entity type must not be {@literal null}. * @param sort the sorting that should be used on the result. * @return a non-null sorted list with all the matching results. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ - Iterable select(Example example, Sort sort); + Iterable select(Query query, Class entityClass, Sort sort); /** - * Determine whether the result matches {@link Example} + * Determine whether there are aggregates that match the {@link Query} * - * @param example must not be {@literal null}. + * @param query must not be {@literal null}. + * @param entityClass the entity type must not be {@literal null}. * @return {@literal true} if the object exists. */ - boolean exists(Example example); + boolean exists(Query query, Class entityClass); /** - * Counts the number of aggregates of a given type that match the given example. + * Counts the number of aggregates of a given type that match the given query. * - * @param example the example to match. + * @param query must not be {@literal null}. + * @param entityClass the entity type must not be {@literal null}. * @return the number of instances stored in the database. Guaranteed to be not {@code null}. */ - long count(Example example); + long count(Query query, Class entityClass); /** - * Returns a {@link Page} of entities matching the given {@link Example}. In case no match could be found, an empty + * Returns a {@link Page} of entities matching the given {@link Query}. In case no match could be found, an empty * {@link Page} is returned. - * - * @param example must not be null + * + * @param query must not be {@literal null}. + * @param entityClass the entity type must not be {@literal null}. * @param pageable can be null. * @return a {@link Page} of entities matching the given {@link Example}. */ - Page select(Example example, Pageable pageable); + Page select(Query query, Class entityClass, Pageable pageable); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index 039bfb9554..f42eb69427 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -24,7 +24,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -44,7 +43,6 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.mapping.event.*; import org.springframework.data.relational.core.query.Query; -import org.springframework.data.relational.repository.query.RelationalExampleMapper; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -71,7 +69,6 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { private final DataAccessStrategy accessStrategy; private final AggregateChangeExecutor executor; - private final RelationalExampleMapper exampleMapper; private final JdbcConverter converter; private EntityCallbacks entityCallbacks = EntityCallbacks.create(); @@ -101,7 +98,6 @@ public JdbcAggregateTemplate(ApplicationContext publisher, RelationalMappingCont this.jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter(context); this.executor = new AggregateChangeExecutor(converter, accessStrategy); - this.exampleMapper = new RelationalExampleMapper(converter.getMappingContext()); setEntityCallbacks(EntityCallbacks.create(publisher)); } @@ -129,7 +125,6 @@ public JdbcAggregateTemplate(ApplicationEventPublisher publisher, RelationalMapp this.jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter(context); this.executor = new AggregateChangeExecutor(converter, accessStrategy); - this.exampleMapper = new RelationalExampleMapper(converter.getMappingContext()); } /** @@ -242,46 +237,31 @@ public Page findAll(Class domainType, Pageable pageable) { } @Override - public Optional selectOne(Example example) { - Query query = this.exampleMapper.getMappedExample(example); - Class probeType = example.getProbeType(); - - return accessStrategy.selectOne(query, probeType); + public Optional selectOne(Query query, Class entityClass) { + return accessStrategy.selectOne(query, entityClass); } @Override - public Iterable select(Example example, Sort sort) { - Query query = this.exampleMapper.getMappedExample(example).sort(sort); - Class probeType = example.getProbeType(); - - return accessStrategy.select(query, probeType); + public Iterable select(Query query, Class entityClass, Sort sort) { + return accessStrategy.select(query, entityClass); } @Override - public boolean exists(Example example) { - Query query = this.exampleMapper.getMappedExample(example); - - Class probeType = example.getProbeType(); - - return accessStrategy.exists(query, probeType); + public boolean exists(Query query, Class entityClass) { + return accessStrategy.exists(query, entityClass); } @Override - public long count(Example example) { - Query query = this.exampleMapper.getMappedExample(example); - Class probeType = example.getProbeType(); - return accessStrategy.count(query, probeType); + public long count(Query query, Class entityClass) { + return accessStrategy.count(query, entityClass); } @Override - public Page select(Example example, Pageable pageable) { - Query query = this.exampleMapper.getMappedExample(example); - Class probeType = example.getProbeType(); - - Iterable items = triggerAfterConvert(accessStrategy.select(query, probeType, pageable)); + public Page select(Query query, Class entityClass, Pageable pageable) { + Iterable items = triggerAfterConvert(accessStrategy.select(query, entityClass, pageable)); List content = StreamSupport.stream(items.spliterator(), false).collect(Collectors.toList()); - return PageableExecutionUtils.getPage(content, pageable, () -> accessStrategy.count(query, probeType)); + return PageableExecutionUtils.getPage(content, pageable, () -> accessStrategy.count(query, entityClass)); } /* diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java index b6bebae247..f68ecc2dc8 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java @@ -122,7 +122,8 @@ protected Object getTargetRepository(RepositoryInformation repositoryInformation RelationalPersistentEntity persistentEntity = context .getRequiredPersistentEntity(repositoryInformation.getDomainType()); - return getTargetRepositoryViaReflection(repositoryInformation.getRepositoryBaseClass(), template, persistentEntity); + return getTargetRepositoryViaReflection(repositoryInformation, template, persistentEntity, + converter); } @Override diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index 9edafd6eec..f271ff9d46 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -24,7 +24,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.JdbcAggregateOperations; +import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.relational.repository.query.RelationalExampleMapper; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.FluentQuery; @@ -42,18 +44,22 @@ * @author Diego Krupitza */ @Transactional(readOnly = true) -public class SimpleJdbcRepository implements CrudRepository, PagingAndSortingRepository, QueryByExampleExecutor { +public class SimpleJdbcRepository + implements CrudRepository, PagingAndSortingRepository, QueryByExampleExecutor { private final JdbcAggregateOperations entityOperations; private final PersistentEntity entity; + private final RelationalExampleMapper exampleMapper; - public SimpleJdbcRepository(JdbcAggregateOperations entityOperations, PersistentEntity entity) { + public SimpleJdbcRepository(JdbcAggregateOperations entityOperations, PersistentEntity entity, + JdbcConverter converter) { Assert.notNull(entityOperations, "EntityOperations must not be null."); Assert.notNull(entity, "Entity must not be null."); this.entityOperations = entityOperations; this.entity = entity; + this.exampleMapper = new RelationalExampleMapper(converter.getMappingContext()); } @Transactional @@ -139,7 +145,7 @@ public Page findAll(Pageable pageable) { @Override public Optional findOne(Example example) { Assert.notNull(example, "Example must not be null!"); - return this.entityOperations.selectOne(example); + return this.entityOperations.selectOne(this.exampleMapper.getMappedExample(example), example.getProbeType()); } @Override @@ -154,28 +160,28 @@ public Iterable findAll(Example example, Sort sort) { Assert.notNull(example, "Example must not be null!"); Assert.notNull(sort, "Sort must not be null!"); - return this.entityOperations.select(example, sort); + return this.entityOperations.select(this.exampleMapper.getMappedExample(example), example.getProbeType(), sort); } @Override public Page findAll(Example example, Pageable pageable) { Assert.notNull(example, "Example must not be null!"); - return this.entityOperations.select(example, pageable); + return this.entityOperations.select(this.exampleMapper.getMappedExample(example), example.getProbeType(), pageable); } @Override public long count(Example example) { Assert.notNull(example, "Example must not be null!"); - return this.entityOperations.count(example); + return this.entityOperations.count(this.exampleMapper.getMappedExample(example), example.getProbeType()); } @Override public boolean exists(Example example) { Assert.notNull(example, "Example must not be null!"); - return this.entityOperations.exists(example); + return this.entityOperations.exists(this.exampleMapper.getMappedExample(example), example.getProbeType()); } @Override diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 99d05a6eef..1b8361b5b0 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -58,7 +58,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jdbc.core.mapping.AggregateReference; -import org.springframework.data.relational.repository.Lock; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java index a94b535b5c..cd901b3df9 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java @@ -64,6 +64,7 @@ * @author Evgeni Dimitrov * @author Fei Dong * @author Chirag Tailor + * @author Diego Krupitza */ @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = TestConfiguration.class) @@ -175,7 +176,8 @@ Dialect jdbcDialect(@Qualifier("qualifierJdbcOperations") NamedParameterJdbcOper private static class DummyRepositoryBaseClass implements CrudRepository { - DummyRepositoryBaseClass(JdbcAggregateTemplate template, PersistentEntity persistentEntity) { + DummyRepositoryBaseClass(JdbcAggregateTemplate template, PersistentEntity persistentEntity, + JdbcConverter converter) { } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepositoryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepositoryUnitTests.java index e5836503b3..47bd009b8e 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepositoryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepositoryUnitTests.java @@ -24,6 +24,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.jdbc.core.JdbcAggregateOperations; +import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; /** @@ -36,11 +37,12 @@ public class SimpleJdbcRepositoryUnitTests { @Mock JdbcAggregateOperations operations; @Mock RelationalPersistentEntity entity; + @Mock JdbcConverter converter; @Test // DATAJDBC-252 public void saveReturnsEntityProducedByOperations() { - SimpleJdbcRepository repository = new SimpleJdbcRepository<>(operations, entity); + SimpleJdbcRepository repository = new SimpleJdbcRepository<>(operations, entity,converter); Sample expected = new Sample(); doReturn(expected).when(operations).save(any()); From ef49e543301e99c301420919ae9a27bd98e7a2a8 Mon Sep 17 00:00:00 2001 From: Diego Krupitza Date: Sat, 9 Apr 2022 17:18:29 +0200 Subject: [PATCH 51/51] Support of QueryByExample `FetchableFluentQuery`. --- .../FetchableFluentQueryByExample.java | 124 +++++++++++++ .../support/FluentQuerySupport.java | 127 +++++++++++++ .../support/SimpleJdbcRepository.java | 8 +- .../JdbcRepositoryIntegrationTests.java | 168 ++++++++++++++++++ 4 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FetchableFluentQueryByExample.java create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FluentQuerySupport.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FetchableFluentQueryByExample.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FetchableFluentQueryByExample.java new file mode 100644 index 0000000000..9c6aebddcb --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FetchableFluentQueryByExample.java @@ -0,0 +1,124 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository.support; + +import java.util.Collections; +import java.util.List; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jdbc.core.JdbcAggregateOperations; +import org.springframework.data.relational.core.query.Query; +import org.springframework.data.relational.repository.query.RelationalExampleMapper; + +/** + * {@link org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery} using {@link Example}. + * + * @author Diego Krupitza + */ +class FetchableFluentQueryByExample extends FluentQuerySupport { + + private final RelationalExampleMapper exampleMapper; + private final JdbcAggregateOperations entityOperations; + + FetchableFluentQueryByExample(Example example, Class resultType, RelationalExampleMapper exampleMapper, + JdbcAggregateOperations entityOperations) { + this(example, Sort.unsorted(), resultType, Collections.emptyList(), exampleMapper, entityOperations); + } + + FetchableFluentQueryByExample(Example example, Sort sort, Class resultType, List fieldsToInclude, + RelationalExampleMapper exampleMapper, JdbcAggregateOperations entityOperations) { + super(example, sort, resultType, fieldsToInclude); + this.exampleMapper = exampleMapper; + this.entityOperations = entityOperations; + } + + @Override + public R oneValue() { + return this.entityOperations.selectOne(createQuery(), getExampleType()) + .map(item -> this.getConversionFunction().apply(item)).get(); + } + + @Override + public R firstValue() { + return this.getConversionFunction() + .apply(this.entityOperations.select(createQuery(), getExampleType(), getSort()).iterator().next()); + } + + @Override + public List all() { + return StreamSupport + .stream(this.entityOperations.select(createQuery(), getExampleType(), getSort()).spliterator(), false) + .map(item -> this.getConversionFunction().apply(item)).collect(Collectors.toList()); + } + + @Override + public Page page(Pageable pageable) { + return this.entityOperations.select(createQuery(p -> p.with(pageable)), getExampleType(), pageable) + .map(item -> this.getConversionFunction().apply(item)); + } + + @Override + public Stream stream() { + return StreamSupport + .stream(this.entityOperations.select(createQuery(), getExampleType(), getSort()).spliterator(), false) + .map(item -> this.getConversionFunction().apply(item)); + } + + @Override + public long count() { + return this.entityOperations.count(createQuery(), getExampleType()); + } + + @Override + public boolean exists() { + return this.entityOperations.exists(createQuery(), getExampleType()); + } + + private Query createQuery() { + return createQuery(UnaryOperator.identity()); + } + + private Query createQuery(UnaryOperator queryCustomizer) { + + Query query = exampleMapper.getMappedExample(getExample()); + + if (getSort().isSorted()) { + query = query.sort(getSort()); + } + + if (!getFieldsToInclude().isEmpty()) { + query = query.columns(getFieldsToInclude().toArray(new String[0])); + } + + query = queryCustomizer.apply(query); + + return query; + } + + @Override + protected FluentQuerySupport create(Example example, Sort sort, Class resultType, + List fieldsToInclude) { + return new FetchableFluentQueryByExample<>(example, sort, resultType, fieldsToInclude, this.exampleMapper, + this.entityOperations); + } +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FluentQuerySupport.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FluentQuerySupport.java new file mode 100644 index 0000000000..50506b505a --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/FluentQuerySupport.java @@ -0,0 +1,127 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.data.jdbc.repository.support; + +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Sort; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; +import org.springframework.data.repository.query.FluentQuery; +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +/** + * Support class for {@link FluentQuery.FetchableFluentQuery} implementations. + * + * @author Diego Krupitza + */ +abstract class FluentQuerySupport implements FluentQuery.FetchableFluentQuery { + + private final Example example; + private final Sort sort; + private final Class resultType; + private final List fieldsToInclude; + + private final SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory(); + + FluentQuerySupport(Example example, Sort sort, Class resultType, List fieldsToInclude) { + this.example = example; + this.sort = sort; + this.resultType = resultType; + this.fieldsToInclude = fieldsToInclude; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.query.FluentQuery.ReactiveFluentQuery#sortBy(org.springframework.data.domain.Sort) + */ + @Override + public FetchableFluentQuery sortBy(Sort sort) { + + Assert.notNull(sort, "Sort must not be null!"); + + return create(example, sort, resultType, fieldsToInclude); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.query.FluentQuery.ReactiveFluentQuery#as(java.lang.Class) + */ + @Override + public FetchableFluentQuery as(Class projection) { + + Assert.notNull(projection, "Projection target type must not be null!"); + + return create(example, sort, projection, fieldsToInclude); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.query.FluentQuery.ReactiveFluentQuery#project(java.util.Collection) + */ + @Override + public FetchableFluentQuery project(Collection properties) { + + Assert.notNull(properties, "Projection properties must not be null!"); + + return create(example, sort, resultType, new ArrayList<>(properties)); + } + + protected abstract FluentQuerySupport create(Example example, Sort sort, Class resultType, + List fieldsToInclude); + + Class getExampleType() { + return this.example.getProbeType(); + } + + Example getExample() { + return this.example; + } + + Sort getSort() { + return sort; + } + + Class getResultType() { + return resultType; + } + + List getFieldsToInclude() { + return fieldsToInclude; + } + + private Function getConversionFunction(Class inputType, Class targetType) { + + if (targetType.isAssignableFrom(inputType)) { + return (Function) Function.identity(); + } + + if (targetType.isInterface()) { + return o -> projectionFactory.createProjection(targetType, o); + } + + return o -> DefaultConversionService.getSharedInstance().convert(o, targetType); + } + + protected Function getConversionFunction() { + return getConversionFunction(this.example.getProbeType(), getResultType()); + } + +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java index f271ff9d46..6d9ed6bebe 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/SimpleJdbcRepository.java @@ -186,6 +186,12 @@ public boolean exists(Example example) { @Override public R findBy(Example example, Function, R> queryFunction) { - throw new UnsupportedOperationException("Not implemented"); + Assert.notNull(example, "Sample must not be null!"); + Assert.notNull(queryFunction, "Query function must not be null!"); + + FluentQuery.FetchableFluentQuery fluentQuery = new FetchableFluentQueryByExample<>(example, + example.getProbeType(), this.exampleMapper, this.entityOperations); + + return queryFunction.apply(fluentQuery); } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 1b8361b5b0..210789aa04 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -57,6 +57,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; @@ -73,6 +74,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; +import org.springframework.data.repository.query.FluentQuery; import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.QueryByExampleExecutor; import org.springframework.jdbc.core.JdbcTemplate; @@ -974,6 +976,168 @@ void countByExampleComplex() { assertThat(count).isOne(); } + @Test + void fetchByExampleFluentAllSimple() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity third = createDummyEntity(); + third.setName(searchName); + third.setPointInTime(now.minusSeconds(200000)); + third = repository.save(third); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + List matches = repository.findBy(example, p -> p.sortBy(Sort.by("pointInTime").descending()).all()); + assertThat(matches).hasSize(2).contains(two, third); + assertThat(matches.get(0)).isEqualTo(two); + } + + @Test + void fetchByExampleFluentCountSimple() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity third = createDummyEntity(); + third.setName(searchName); + third.setPointInTime(now.minusSeconds(200000)); + third = repository.save(third); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + Long matches = repository.findBy(example, FluentQuery.FetchableFluentQuery::count); + assertThat(matches).isEqualTo(2); + } + + @Test + void fetchByExampleFluentOnlyInstantFirstSimple() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity third = createDummyEntity(); + third.setName(searchName); + third.setPointInTime(now.minusSeconds(200000)); + third = repository.save(third); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + Optional matches = repository.findBy(example, + p -> p.sortBy(Sort.by("pointInTime").descending()).first()); + assertThat(matches).contains(two); + } + + @Test + void fetchByExampleFluentOnlyInstantOneValueError() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity third = createDummyEntity(); + third.setName(searchName); + third.setPointInTime(now.minusSeconds(200000)); + third = repository.save(third); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + assertThatThrownBy(() -> repository.findBy(example, p -> p.sortBy(Sort.by("pointInTime").descending()).one())) + .isInstanceOf(IncorrectResultSizeDataAccessException.class).hasMessageContaining("expected 1, actual 2"); + } + + @Test + void fetchByExampleFluentOnlyInstantOneValueSimple() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + Optional match = repository.findBy(example, p -> p.sortBy(Sort.by("pointInTime").descending()).one()); + + assertThat(match).contains(two); + } + + @Test + void fetchByExampleFluentOnlyInstantOneValueAsSimple() { + String searchName = "Diego"; + + Instant now = Instant.now(); + + final DummyEntity one = repository.save(createDummyEntity()); + + DummyEntity two = createDummyEntity(); + + two.setName(searchName); + two.setPointInTime(now.minusSeconds(10000)); + two = repository.save(two); + + DummyEntity exampleEntitiy = createDummyEntity(); + exampleEntitiy.setName(searchName); + + Example example = Example.of(exampleEntitiy); + + Optional match = repository.findBy(example, p -> p.as(DummyProjectExample.class).one()); + + assertThat(match.get().getName()).contains(two.getName()); + } + private Instant createDummyBeforeAndAfterNow() { Instant now = Instant.now(); @@ -997,6 +1161,10 @@ private Instant createDummyBeforeAndAfterNow() { return now; } + interface DummyProjectExample { + String getName(); + } + interface DummyEntityRepository extends CrudRepository, QueryByExampleExecutor { @Lock(LockMode.PESSIMISTIC_WRITE)