diff --git a/pom.xml b/pom.xml
index 4959b322a..71216b1fb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
0.1.4
+
1.4.200
2.2.8
7.0.0.jre8
3.5.0
@@ -98,6 +99,24 @@
org.apache.maven.plugins
maven-surefire-plugin
+
+ h2-test
+ test
+
+ test
+
+
+
+ **/*IntegrationTests.java
+
+
+ **/*HsqlIntegrationTests.java
+
+
+ h2
+
+
+
mysql-test
test
@@ -110,6 +129,7 @@
**/*HsqlIntegrationTests.java
+ **/*H2IntegrationTests.java
mysql
@@ -128,6 +148,7 @@
**/*HsqlIntegrationTests.java
+ **/*H2IntegrationTests.java
postgres
@@ -146,6 +167,7 @@
**/*HsqlIntegrationTests.java
+ **/*H2IntegrationTests.java
mariadb
diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml
index 17204c4a0..1fdf3e615 100644
--- a/spring-data-jdbc/pom.xml
+++ b/spring-data-jdbc/pom.xml
@@ -137,6 +137,13 @@
true
+
+ com.h2database
+ h2
+ ${h2.version}
+ test
+
+
org.hsqldb
hsqldb
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java
index 70e68d8c8..a5dfb7a6e 100644
--- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java
@@ -158,7 +158,7 @@ class AggregateChangeExecutor {
.getRequiredPersistentEntity(action.getEntityType());
PersistentPropertyAccessor propertyAccessor = converter.getPropertyAccessor(persistentEntity, originalEntity);
- if (generatedId != null) {
+ if (generatedId != null && persistentEntity.hasIdProperty()) {
propertyAccessor.setProperty(persistentEntity.getRequiredIdProperty(), generatedId);
}
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java
index 9013be20e..2784e7e97 100644
--- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java
@@ -27,6 +27,7 @@ import javax.sql.DataSource;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.data.relational.core.dialect.Dialect;
+import org.springframework.data.relational.core.dialect.H2Dialect;
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
import org.springframework.data.relational.core.dialect.MySqlDialect;
import org.springframework.data.relational.core.dialect.PostgresDialect;
@@ -110,6 +111,9 @@ public class DialectResolver {
if (name.contains("hsql")) {
return HsqlDbDialect.INSTANCE;
}
+ if (name.contains("h2")) {
+ return H2Dialect.INSTANCE;
+ }
if (name.contains("mysql")) { // catches also mariadb
return new MySqlDialect(getIdentifierProcessing(metaData));
}
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 6066508e1..cd3570d3c 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
@@ -529,11 +529,12 @@ public class JdbcAggregateTemplateIntegrationTests {
assertThat(reloaded.digits).isEqualTo(new String[] { "one", "two", "three" });
}
- @Test // DATAJDBC-259
+ @Test // DATAJDBC-259, DATAJDBC-512
public void saveAndLoadAnEntityWithMultidimensionalArray() {
// MySQL and other do not support array datatypes. See
// https://dev.mysql.com/doc/refman/8.0/en/data-type-overview.html
+ assumeNot("h2");
assumeNot("mysql");
assumeNot("mariadb");
assumeNot("mssql");
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationIntegrationTests.java
similarity index 93%
rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java
rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationIntegrationTests.java
index 4e7162eb8..7524bc0df 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationIntegrationTests.java
@@ -26,9 +26,11 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
+import org.junit.Assume;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -40,8 +42,7 @@ import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.lang.Nullable;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
import org.springframework.transaction.annotation.Transactional;
@@ -51,11 +52,21 @@ import org.springframework.transaction.annotation.Transactional;
*
* @author Jens Schauder
* @author Kazuki Shimizu
+ * @author Mark Paluch
*/
-@ContextConfiguration
-@ActiveProfiles("hsql")
@Transactional
-public class QueryAnnotationHsqlIntegrationTests {
+public class QueryAnnotationIntegrationTests {
+
+ @Configuration
+ @Import(TestConfiguration.class)
+ @EnableJdbcRepositories(considerNestedRepositories = true)
+ static class Config {
+
+ @Bean
+ Class> testClass() {
+ return QueryAnnotationIntegrationTests.class;
+ }
+ }
@Autowired DummyEntityRepository repository;
@@ -65,6 +76,8 @@ public class QueryAnnotationHsqlIntegrationTests {
@Test // DATAJDBC-164
public void executeCustomQueryWithoutParameter() {
+ assumeNot("mysql");
+
repository.save(dummyEntity("Example"));
repository.save(dummyEntity("example"));
repository.save(dummyEntity("EXAMPLE"));
@@ -74,7 +87,6 @@ public class QueryAnnotationHsqlIntegrationTests {
assertThat(entities) //
.extracting(e -> e.name) //
.containsExactlyInAnyOrder("Example", "EXAMPLE");
-
}
@Test // DATAJDBC-164
@@ -89,7 +101,6 @@ public class QueryAnnotationHsqlIntegrationTests {
assertThat(entities) //
.extracting(e -> e.name) //
.containsExactlyInAnyOrder("b");
-
}
@Test // DATAJDBC-172
@@ -100,7 +111,6 @@ public class QueryAnnotationHsqlIntegrationTests {
Optional entity = repository.findByNameAsOptional("a");
assertThat(entity).map(e -> e.name).contains("a");
-
}
@Test // DATAJDBC-172
@@ -111,7 +121,6 @@ public class QueryAnnotationHsqlIntegrationTests {
Optional entity = repository.findByNameAsOptional("x");
assertThat(entity).isNotPresent();
-
}
@Test // DATAJDBC-172
@@ -123,7 +132,6 @@ public class QueryAnnotationHsqlIntegrationTests {
assertThat(entity).isNotNull();
assertThat(entity.name).isEqualTo("a");
-
}
@Test // DATAJDBC-172
@@ -134,7 +142,6 @@ public class QueryAnnotationHsqlIntegrationTests {
DummyEntity entity = repository.findByNameAsEntity("x");
assertThat(entity).isNull();
-
}
@Test // DATAJDBC-172
@@ -168,12 +175,13 @@ public class QueryAnnotationHsqlIntegrationTests {
assertThat(entities) //
.extracting(e -> e.name) //
.containsExactlyInAnyOrder("a", "b");
-
}
@Test // DATAJDBC-175
public void executeCustomQueryWithReturnTypeIsNumber() {
+ assumeNot("mysql");
+
repository.save(dummyEntity("aaa"));
repository.save(dummyEntity("bbb"));
repository.save(dummyEntity("cac"));
@@ -181,24 +189,26 @@ public class QueryAnnotationHsqlIntegrationTests {
int count = repository.countByNameContaining("a");
assertThat(count).isEqualTo(2);
-
}
@Test // DATAJDBC-175
public void executeCustomQueryWithReturnTypeIsBoolean() {
+ assumeNot("mysql");
+
repository.save(dummyEntity("aaa"));
repository.save(dummyEntity("bbb"));
repository.save(dummyEntity("cac"));
assertThat(repository.existsByNameContaining("a")).isTrue();
assertThat(repository.existsByNameContaining("d")).isFalse();
-
}
@Test // DATAJDBC-175
public void executeCustomQueryWithReturnTypeIsDate() {
+ assumeNot("mysql");
+
// Since Timestamp extends Date the repository returns the Timestamp as it comes from the database.
// Trying to compare that to an actual Date results in non deterministic results, so we have to use an actual
// Timestamp.
@@ -210,12 +220,14 @@ public class QueryAnnotationHsqlIntegrationTests {
@Test // DATAJDBC-175
public void executeCustomQueryWithReturnTypeIsLocalDateTimeList() {
+ // mysql does not support plain VALUES(…)
+ assumeNot("mysql");
+
LocalDateTime preciseNow = LocalDateTime.now();
LocalDateTime truncatedNow = truncateSubmillis(preciseNow);
repository.nowWithLocalDateTimeList() //
.forEach(d -> assertThat(d).isAfterOrEqualTo(truncatedNow));
-
}
@Test // DATAJDBC-182
@@ -258,6 +270,10 @@ public class QueryAnnotationHsqlIntegrationTests {
@Test // DATAJDBC-175
public void executeCustomQueryWithImmutableResultType() {
+ // mysql does not support plain VALUES(…)
+
+ assumeNot("mysql");
+
assertThat(repository.immutableTuple()).isEqualTo(new DummyEntityRepository.ImmutableTuple("one", "two", 3));
}
@@ -274,15 +290,11 @@ public class QueryAnnotationHsqlIntegrationTests {
return entity;
}
- @Configuration
- @Import(TestConfiguration.class)
- @EnableJdbcRepositories(considerNestedRepositories = true)
- static class Config {
+ private static void assumeNot(String dbProfileName) {
- @Bean
- Class> testClass() {
- return QueryAnnotationHsqlIntegrationTests.class;
- }
+ Assume.assumeTrue(
+ "true".equalsIgnoreCase(ProfileValueUtils.retrieveProfileValueSource(QueryAnnotationIntegrationTests.class)
+ .get("current.database.is.not." + dbProfileName)));
}
private static class DummyEntity {
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/H2DataSourceConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/H2DataSourceConfiguration.java
new file mode 100644
index 000000000..1efa9fd28
--- /dev/null
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/H2DataSourceConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 the original author 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.testing;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+/**
+ * {@link DataSource} setup for H2.
+ *
+ * @author Mark Paluch
+ */
+@Configuration
+@Profile({ "h2" })
+class H2DataSourceConfiguration {
+
+ @Autowired Class> context;
+
+ @Bean
+ DataSource dataSource() {
+
+ return new EmbeddedDatabaseBuilder() //
+ .generateUniqueName(true) //
+ .setType(EmbeddedDatabaseType.H2) //
+ .setScriptEncoding("UTF-8") //
+ .ignoreFailedDrops(true) //
+ .addScript(TestUtils.createScriptName(context, "h2")) //
+ .build();
+ }
+}
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java
index f1f087ba4..711ca671f 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/HsqlDataSourceConfiguration.java
@@ -15,12 +15,15 @@
*/
package org.springframework.data.jdbc.testing;
+import java.util.Arrays;
+
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql
new file mode 100644
index 000000000..cb6dceaaa
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql
@@ -0,0 +1,305 @@
+CREATE TABLE LEGO_SET
+(
+ "id1" SERIAL PRIMARY KEY,
+ NAME VARCHAR(30)
+);
+CREATE TABLE MANUAL
+(
+ "id2" SERIAL PRIMARY KEY,
+ LEGO_SET BIGINT,
+ "alternative" BIGINT,
+ CONTENT VARCHAR(2000)
+);
+
+ALTER TABLE MANUAL
+ ADD FOREIGN KEY (LEGO_SET)
+ REFERENCES LEGO_SET ("id1");
+
+CREATE TABLE ONE_TO_ONE_PARENT
+(
+ "id3" SERIAL PRIMARY KEY,
+ content VARCHAR(30)
+);
+CREATE TABLE Child_No_Id
+(
+ ONE_TO_ONE_PARENT INTEGER PRIMARY KEY,
+ content VARCHAR(30)
+);
+
+CREATE TABLE LIST_PARENT
+(
+ "id4" SERIAL PRIMARY KEY,
+ NAME VARCHAR(100)
+);
+
+CREATE TABLE element_no_id
+(
+ content VARCHAR(100),
+ LIST_PARENT_key BIGINT,
+ LIST_PARENT INTEGER
+);
+
+CREATE TABLE "ARRAY_OWNER"
+(
+ ID SERIAL PRIMARY KEY,
+ DIGITS ARRAY[10] NOT NULL,
+ MULTIDIMENSIONAL ARRAY[10] NULL
+);
+
+CREATE TABLE BYTE_ARRAY_OWNER
+(
+ ID SERIAL PRIMARY KEY,
+ BINARY_DATA BYTEA NOT NULL
+);
+
+CREATE TABLE CHAIN4
+(
+ FOUR SERIAL PRIMARY KEY,
+ FOUR_VALUE VARCHAR(20)
+);
+
+CREATE TABLE CHAIN3
+(
+ THREE SERIAL PRIMARY KEY,
+ THREE_VALUE VARCHAR(20),
+ CHAIN4 BIGINT,
+ FOREIGN KEY (CHAIN4) REFERENCES CHAIN4 (FOUR)
+);
+
+CREATE TABLE CHAIN2
+(
+ TWO SERIAL PRIMARY KEY,
+ TWO_VALUE VARCHAR(20),
+ CHAIN3 BIGINT,
+ FOREIGN KEY (CHAIN3) REFERENCES CHAIN3 (THREE)
+);
+
+CREATE TABLE CHAIN1
+(
+ ONE SERIAL PRIMARY KEY,
+ ONE_VALUE VARCHAR(20),
+ CHAIN2 BIGINT,
+ FOREIGN KEY (CHAIN2) REFERENCES CHAIN2 (TWO)
+);
+
+CREATE TABLE CHAIN0
+(
+ ZERO SERIAL PRIMARY KEY,
+ ZERO_VALUE VARCHAR(20),
+ CHAIN1 BIGINT,
+ FOREIGN KEY (CHAIN1) REFERENCES CHAIN1 (ONE)
+);
+
+CREATE TABLE NO_ID_CHAIN4
+(
+ FOUR SERIAL PRIMARY KEY,
+ FOUR_VALUE VARCHAR(20)
+);
+
+CREATE TABLE NO_ID_CHAIN3
+(
+ THREE_VALUE VARCHAR(20),
+ NO_ID_CHAIN4 BIGINT,
+ FOREIGN KEY (NO_ID_CHAIN4) REFERENCES NO_ID_CHAIN4 (FOUR)
+);
+
+CREATE TABLE NO_ID_CHAIN2
+(
+ TWO_VALUE VARCHAR(20),
+ NO_ID_CHAIN4 BIGINT,
+ FOREIGN KEY (NO_ID_CHAIN4) REFERENCES NO_ID_CHAIN4 (FOUR)
+);
+
+CREATE TABLE NO_ID_CHAIN1
+(
+ ONE_VALUE VARCHAR(20),
+ NO_ID_CHAIN4 BIGINT,
+ FOREIGN KEY (NO_ID_CHAIN4) REFERENCES NO_ID_CHAIN4 (FOUR)
+);
+
+CREATE TABLE NO_ID_CHAIN0
+(
+ ZERO_VALUE VARCHAR(20),
+ NO_ID_CHAIN4 BIGINT,
+ FOREIGN KEY (NO_ID_CHAIN4) REFERENCES NO_ID_CHAIN4 (FOUR)
+);
+
+
+CREATE TABLE NO_ID_LIST_CHAIN4
+(
+ FOUR SERIAL PRIMARY KEY,
+ FOUR_VALUE VARCHAR(20)
+);
+
+CREATE TABLE NO_ID_LIST_CHAIN3
+(
+ THREE_VALUE VARCHAR(20),
+ NO_ID_LIST_CHAIN4 BIGINT,
+ NO_ID_LIST_CHAIN4_KEY BIGINT,
+ PRIMARY KEY (NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY),
+ FOREIGN KEY (NO_ID_LIST_CHAIN4) REFERENCES NO_ID_LIST_CHAIN4 (FOUR)
+);
+
+CREATE TABLE NO_ID_LIST_CHAIN2
+(
+ TWO_VALUE VARCHAR(20),
+ NO_ID_LIST_CHAIN4 BIGINT,
+ NO_ID_LIST_CHAIN4_KEY BIGINT,
+ NO_ID_LIST_CHAIN3_KEY BIGINT,
+ PRIMARY KEY (NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY),
+ FOREIGN KEY (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY
+ ) REFERENCES NO_ID_LIST_CHAIN3 (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY
+ )
+);
+
+CREATE TABLE NO_ID_LIST_CHAIN1
+(
+ ONE_VALUE VARCHAR(20),
+ NO_ID_LIST_CHAIN4 BIGINT,
+ NO_ID_LIST_CHAIN4_KEY BIGINT,
+ NO_ID_LIST_CHAIN3_KEY BIGINT,
+ NO_ID_LIST_CHAIN2_KEY BIGINT,
+ PRIMARY KEY (NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY,
+ NO_ID_LIST_CHAIN2_KEY),
+ FOREIGN KEY (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY
+ ) REFERENCES NO_ID_LIST_CHAIN2 (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY
+ )
+);
+
+CREATE TABLE NO_ID_LIST_CHAIN0
+(
+ ZERO_VALUE VARCHAR(20),
+ NO_ID_LIST_CHAIN4 BIGINT,
+ NO_ID_LIST_CHAIN4_KEY BIGINT,
+ NO_ID_LIST_CHAIN3_KEY BIGINT,
+ NO_ID_LIST_CHAIN2_KEY BIGINT,
+ NO_ID_LIST_CHAIN1_KEY BIGINT,
+ PRIMARY KEY (NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY,
+ NO_ID_LIST_CHAIN2_KEY,
+ NO_ID_LIST_CHAIN1_KEY),
+ FOREIGN KEY (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY,
+ NO_ID_LIST_CHAIN2_KEY
+ ) REFERENCES NO_ID_LIST_CHAIN1 (
+ NO_ID_LIST_CHAIN4,
+ NO_ID_LIST_CHAIN4_KEY,
+ NO_ID_LIST_CHAIN3_KEY,
+ NO_ID_LIST_CHAIN2_KEY
+ )
+);
+
+
+
+CREATE TABLE NO_ID_MAP_CHAIN4
+(
+ FOUR SERIAL PRIMARY KEY,
+ FOUR_VALUE VARCHAR(20)
+);
+
+CREATE TABLE NO_ID_MAP_CHAIN3
+(
+ THREE_VALUE VARCHAR(20),
+ NO_ID_MAP_CHAIN4 BIGINT,
+ NO_ID_MAP_CHAIN4_KEY VARCHAR(20),
+ PRIMARY KEY (NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY),
+ FOREIGN KEY (NO_ID_MAP_CHAIN4) REFERENCES NO_ID_MAP_CHAIN4 (FOUR)
+);
+
+CREATE TABLE NO_ID_MAP_CHAIN2
+(
+ TWO_VALUE VARCHAR(20),
+ NO_ID_MAP_CHAIN4 BIGINT,
+ NO_ID_MAP_CHAIN4_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN3_KEY VARCHAR(20),
+ PRIMARY KEY (NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY),
+ FOREIGN KEY (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY
+ ) REFERENCES NO_ID_MAP_CHAIN3 (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY
+ )
+);
+
+CREATE TABLE NO_ID_MAP_CHAIN1
+(
+ ONE_VALUE VARCHAR(20),
+ NO_ID_MAP_CHAIN4 BIGINT,
+ NO_ID_MAP_CHAIN4_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN3_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN2_KEY VARCHAR(20),
+ PRIMARY KEY (NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY,
+ NO_ID_MAP_CHAIN2_KEY),
+ FOREIGN KEY (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY
+ ) REFERENCES NO_ID_MAP_CHAIN2 (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY
+ )
+);
+
+CREATE TABLE NO_ID_MAP_CHAIN0
+(
+ ZERO_VALUE VARCHAR(20),
+ NO_ID_MAP_CHAIN4 BIGINT,
+ NO_ID_MAP_CHAIN4_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN3_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN2_KEY VARCHAR(20),
+ NO_ID_MAP_CHAIN1_KEY VARCHAR(20),
+ PRIMARY KEY (NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY,
+ NO_ID_MAP_CHAIN2_KEY,
+ NO_ID_MAP_CHAIN1_KEY),
+ FOREIGN KEY (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY,
+ NO_ID_MAP_CHAIN2_KEY
+ ) REFERENCES NO_ID_MAP_CHAIN1 (
+ NO_ID_MAP_CHAIN4,
+ NO_ID_MAP_CHAIN4_KEY,
+ NO_ID_MAP_CHAIN3_KEY,
+ NO_ID_MAP_CHAIN2_KEY
+ )
+);
+
+CREATE TABLE "VERSIONED_AGGREGATE"
+(
+ ID SERIAL PRIMARY KEY,
+ VERSION BIGINT
+);
+
+CREATE TABLE WITH_READ_ONLY
+(
+ ID SERIAL PRIMARY KEY,
+ NAME VARCHAR(200),
+ READ_ONLY VARCHAR(200) DEFAULT 'from-db'
+);
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-h2.sql
new file mode 100644
index 000000000..aab1bd853
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.config/EnableJdbcRepositoriesIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE Dummy_Entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY)
\ No newline at end of file
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationHsqlIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-h2.sql
similarity index 100%
rename from spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationHsqlIntegrationTests-hsql.sql
rename to spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-h2.sql
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-hsql.sql
new file mode 100644
index 000000000..12c793eaa
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-hsql.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( 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.query/QueryAnnotationIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-mariadb.sql
new file mode 100644
index 000000000..dd786b053
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-mariadb.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( id BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-mysql.sql
new file mode 100644
index 000000000..dd786b053
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-mysql.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( id BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-postgres.sql
new file mode 100644
index 000000000..c8c5fb08f
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository.query/QueryAnnotationIntegrationTests-postgres.sql
@@ -0,0 +1,2 @@
+DROP TABLE IF EXISTS dummy_entity;
+CREATE TABLE dummy_entity ( id SERIAL PRIMARY KEY, NAME VARCHAR(100));
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCustomConversionIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCustomConversionIntegrationTests-h2.sql
new file mode 100644
index 000000000..dd3175f7e
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCustomConversionIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE ENTITY_WITH_STRINGY_BIG_DECIMAL ( id IDENTITY PRIMARY KEY, Stringy_number DECIMAL(20,10))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedImmutableIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedImmutableIntegrationTests-h2.sql
new file mode 100644
index 000000000..1000cc556
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedImmutableIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-h2.sql
new file mode 100644
index 000000000..b6619706d
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT)
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests-h2.sql
new file mode 100644
index 000000000..60af8e60c
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests-h2.sql
@@ -0,0 +1,2 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, TEST VARCHAR(100))
+CREATE TABLE dummy_entity2 ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, TEST VARCHAR(100), PREFIX_ATTR BIGINT)
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-h2.sql
new file mode 100644
index 000000000..0a8a90711
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-h2.sql
@@ -0,0 +1,13 @@
+CREATE TABLE dummy_entity
+(
+ id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
+ TEST VARCHAR(100),
+ PREFIX_TEST VARCHAR(100)
+);
+CREATE TABLE dummy_entity2
+(
+ id BIGINT,
+ ORDER_KEY BIGINT,
+ TEST VARCHAR(100),
+ PRIMARY KEY (id, ORDER_KEY)
+)
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests-h2.sql
new file mode 100644
index 000000000..355618114
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests-h2.sql
@@ -0,0 +1,11 @@
+CREATE TABLE dummy_entity
+(
+ ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
+ TEST VARCHAR(100),
+ PREFIX_TEST VARCHAR(100)
+);
+CREATE TABLE dummy_entity2
+(
+ ID BIGINT,
+ TEST VARCHAR(100)
+)
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-h2.sql
new file mode 100644
index 000000000..225c54e88
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIdGenerationIntegrationTests-h2.sql
@@ -0,0 +1,5 @@
+-- noinspection SqlNoDataSourceInspectionForFile
+
+CREATE TABLE ReadOnlyIdEntity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, NAME VARCHAR(100));
+CREATE TABLE PrimitiveIdEntity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, NAME VARCHAR(100));
+CREATE TABLE ImmutableWithManualIdentity (ID BIGINT PRIMARY KEY, NAME VARCHAR(100));
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryInsertExistingIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryInsertExistingIntegrationTests-h2.sql
new file mode 100644
index 000000000..25a09e431
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryInsertExistingIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE dummy_entity ( id_Prop BIGINT PRIMARY KEY, NAME VARCHAR(100))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql
new file mode 100644
index 000000000..6649c1439
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql
@@ -0,0 +1,6 @@
+CREATE TABLE dummy_entity
+(
+ id_Prop BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
+ NAME VARCHAR(100),
+ POINT_IN_TIME TIMESTAMP
+);
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryManipulateDbActionsIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryManipulateDbActionsIntegrationTests-h2.sql
new file mode 100644
index 000000000..616c4a8c8
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryManipulateDbActionsIntegrationTests-h2.sql
@@ -0,0 +1,2 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100), DELETED CHAR(1), log BIGINT);
+CREATE TABLE log ( id BIGINT, TEXT VARCHAR(100));
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-h2.sql
new file mode 100644
index 000000000..8fe6fbee7
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryPropertyConversionIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE ENTITY_WITH_COLUMNS_REQUIRING_CONVERSIONS ( id_Timestamp DATETIME PRIMARY KEY, bool boolean, SOME_ENUM VARCHAR(100), big_Decimal DECIMAL(1025), big_Integer DECIMAL(20), date DATETIME, local_Date_Time DATETIME, zoned_Date_Time VARCHAR(30))
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryQueryMappingConfigurationIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryQueryMappingConfigurationIntegrationTests-h2.sql
new file mode 100644
index 000000000..9d5026bc6
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryQueryMappingConfigurationIntegrationTests-h2.sql
@@ -0,0 +1 @@
+CREATE TABLE car ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, model VARCHAR(100));
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryResultSetExtractorIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryResultSetExtractorIntegrationTests-h2.sql
new file mode 100644
index 000000000..a33c466af
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryResultSetExtractorIntegrationTests-h2.sql
@@ -0,0 +1,3 @@
+CREATE TABLE person ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, name VARCHAR(100));
+CREATE TABLE address ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, street VARCHAR(100), person_id BIGINT);
+ALTER TABLE address ADD FOREIGN KEY (person_id) REFERENCES person(id);
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithCollectionsIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithCollectionsIntegrationTests-h2.sql
new file mode 100644
index 000000000..480b9f278
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithCollectionsIntegrationTests-h2.sql
@@ -0,0 +1,2 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100));
+CREATE TABLE element (id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, content VARCHAR(100), dummy_entity BIGINT);
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithListsIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithListsIntegrationTests-h2.sql
new file mode 100644
index 000000000..73abf96ce
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithListsIntegrationTests-h2.sql
@@ -0,0 +1,2 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100));
+CREATE TABLE element (id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, content VARCHAR(100), Dummy_Entity_key BIGINT, dummy_entity BIGINT);
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithMapsIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithMapsIntegrationTests-h2.sql
new file mode 100644
index 000000000..15d39c175
--- /dev/null
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithMapsIntegrationTests-h2.sql
@@ -0,0 +1,6 @@
+CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100));
+CREATE TABLE element (id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, content VARCHAR(100), Dummy_Entity_key VARCHAR(100), dummy_entity BIGINT);
+
+ALTER TABLE ELEMENT
+ ADD FOREIGN KEY (dummy_entity)
+ REFERENCES dummy_entity(id);
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
new file mode 100644
index 000000000..f8b261866
--- /dev/null
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/H2Dialect.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2019-2020 the original author 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 lombok.RequiredArgsConstructor;
+
+import org.springframework.data.relational.core.sql.IdentifierProcessing;
+import org.springframework.data.relational.core.sql.IdentifierProcessing.LetterCasing;
+import org.springframework.data.relational.core.sql.IdentifierProcessing.Quoting;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+/**
+ * An SQL dialect for H2.
+ *
+ * @author Mark Paluch
+ * @since 2.0
+ */
+public class H2Dialect extends AbstractDialect {
+
+ /**
+ * Singleton instance.
+ */
+ public static final H2Dialect INSTANCE = new H2Dialect();
+
+ protected H2Dialect() {}
+
+ private static final LimitClause LIMIT_CLAUSE = new LimitClause() {
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.LimitClause#getLimit(long)
+ */
+ @Override
+ public String getLimit(long limit) {
+ return "LIMIT " + limit;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.LimitClause#getOffset(long)
+ */
+ @Override
+ public String getOffset(long offset) {
+ return "OFFSET " + offset;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.LimitClause#getClause(long, long)
+ */
+ @Override
+ public String getLimitOffset(long limit, long offset) {
+ return String.format("LIMIT %d OFFSET %d", limit, offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.LimitClause#getClausePosition()
+ */
+ @Override
+ public Position getClausePosition() {
+ return Position.AFTER_ORDER_BY;
+ }
+ };
+
+ private final H2ArrayColumns ARRAY_COLUMNS = new H2ArrayColumns();
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.Dialect#limit()
+ */
+ @Override
+ public LimitClause limit() {
+ return LIMIT_CLAUSE;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.Dialect#getArraySupport()
+ */
+ @Override
+ public ArrayColumns getArraySupport() {
+ return ARRAY_COLUMNS;
+ }
+
+ @RequiredArgsConstructor
+ static class H2ArrayColumns implements ArrayColumns {
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.ArrayColumns#isSupported()
+ */
+ @Override
+ public boolean isSupported() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.ArrayColumns#getArrayType(java.lang.Class)
+ */
+ @Override
+ public Class> getArrayType(Class> userType) {
+
+ Assert.notNull(userType, "Array component type must not be null");
+
+ return ClassUtils.resolvePrimitiveIfNecessary(userType);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.relational.core.dialect.Dialect#getIdentifierProcessing()
+ */
+ @Override
+ public IdentifierProcessing getIdentifierProcessing() {
+ return IdentifierProcessing.create(Quoting.ANSI, LetterCasing.UPPER_CASE);
+ }
+}