diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java index 7b39ada35e1..bc4c2d80d07 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import javax.sql.DataSource; * of a given H2 sequence. * * @author Thomas Risberg + * @author Henning Pöttker * @since 2.5 */ public class H2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { @@ -47,7 +48,7 @@ public class H2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncre @Override protected String getSequenceQuery() { - return "select " + getIncrementerName() + ".nextval from dual"; + return "values next value for " + getIncrementerName(); } } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementerTests.java new file mode 100644 index 00000000000..512e82dea0c --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementerTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2002-2022 the original author 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.jdbc.support.incrementer; + +import java.util.UUID; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.SimpleDriverDataSource; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link H2SequenceMaxValueIncrementer}. + * + * @author Henning Pöttker + * @author Sam Brannen + * @since 5.3.15 + */ +class H2SequenceMaxValueIncrementerTests { + + /** + * Tests that the incrementer works when using the JDBC connection URL used + * in the {@code H2EmbeddedDatabaseConfigurer} which is used transparently + * when using Spring's {@link EmbeddedDatabaseBuilder}. + * + *

In other words, this tests compatibility with the default H2 + * compatibility mode. + */ + @Test + void incrementsSequenceUsingH2EmbeddedDatabaseConfigurer() { + EmbeddedDatabase database = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .generateUniqueName(true) + .addScript("classpath:/org/springframework/jdbc/support/incrementer/schema.sql") + .build(); + + JdbcTemplate jdbcTemplate = new JdbcTemplate(database); + assertThat(jdbcTemplate.queryForObject("values next value for SEQ", int.class)).isEqualTo(1); + + H2SequenceMaxValueIncrementer incrementer = new H2SequenceMaxValueIncrementer(database, "SEQ"); + assertThat(incrementer.nextIntValue()).isEqualTo(2); + assertThat(incrementer.nextStringValue()).isEqualTo("3"); + + database.shutdown(); + } + + /** + * Tests that the incrementer works when using all supported H2 compatibility modes. + * + *

The following modes are only supported with H2 2.x or higher: STRICT, LEGACY, MariaDB + */ + @ParameterizedTest + @ValueSource(strings = { "DB2", "Derby", "HSQLDB", "MSSQLServer", "MySQL", "Oracle", "PostgreSQL" }) + void incrementsSequenceWithExplicitH2CompatibilityMode(String compatibilityMode) { + String connectionUrl = String.format("jdbc:h2:mem:%s;MODE=%s", UUID.randomUUID().toString(), compatibilityMode); + DataSource dataSource = new SimpleDriverDataSource(new org.h2.Driver(), connectionUrl, "sa", ""); + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); + TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + + transactionTemplate.executeWithoutResult(status -> { + jdbcTemplate.execute("CREATE SEQUENCE SEQ"); + assertThat(jdbcTemplate.queryForObject("values next value for SEQ", int.class)).isEqualTo(1); + + H2SequenceMaxValueIncrementer incrementer = new H2SequenceMaxValueIncrementer(dataSource, "SEQ"); + assertThat(incrementer.nextIntValue()).isEqualTo(2); + assertThat(incrementer.nextStringValue()).isEqualTo("3"); + }); + + jdbcTemplate.execute("SHUTDOWN"); + } + +} diff --git a/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-without-separator.sql b/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-without-separator.sql index 4a4dc97f2fb..19af16cc04e 100644 --- a/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-without-separator.sql +++ b/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-without-separator.sql @@ -1,5 +1,5 @@ CREATE TABLE users ( - id INTEGER NOT NULL IDENTITY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL ) \ No newline at end of file diff --git a/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql b/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql index 80ffe23da9a..523c4a7c2b1 100644 --- a/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql +++ b/spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql @@ -1,7 +1,7 @@ DROP TABLE users IF EXISTS; CREATE TABLE users ( - id INTEGER NOT NULL IDENTITY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL ); diff --git a/spring-jdbc/src/test/resources/org/springframework/jdbc/support/incrementer/schema.sql b/spring-jdbc/src/test/resources/org/springframework/jdbc/support/incrementer/schema.sql new file mode 100644 index 00000000000..b74b576ab83 --- /dev/null +++ b/spring-jdbc/src/test/resources/org/springframework/jdbc/support/incrementer/schema.sql @@ -0,0 +1 @@ +CREATE SEQUENCE SEQ; \ No newline at end of file diff --git a/spring-r2dbc/src/test/resources/org/springframework/r2dbc/connection/init/users-schema.sql b/spring-r2dbc/src/test/resources/org/springframework/r2dbc/connection/init/users-schema.sql index 80ffe23da9a..523c4a7c2b1 100644 --- a/spring-r2dbc/src/test/resources/org/springframework/r2dbc/connection/init/users-schema.sql +++ b/spring-r2dbc/src/test/resources/org/springframework/r2dbc/connection/init/users-schema.sql @@ -1,7 +1,7 @@ DROP TABLE users IF EXISTS; CREATE TABLE users ( - id INTEGER NOT NULL IDENTITY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL ); diff --git a/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/db-schema.sql b/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/db-schema.sql index 3dee075af5f..d8ded6eff4b 100644 --- a/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/db-schema.sql +++ b/spring-test/src/test/resources/org/springframework/test/context/junit4/orm/db-schema.sql @@ -2,7 +2,7 @@ DROP TABLE drivers_license IF EXISTS; DROP TABLE person IF EXISTS; CREATE TABLE person ( - id INTEGER NOT NULL IDENTITY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY, name VARCHAR(50) NOT NULL, drivers_license_id INTEGER NOT NULL ); @@ -10,7 +10,7 @@ CREATE UNIQUE INDEX person_name ON person(name); CREATE UNIQUE INDEX person_drivers_license_id ON person(drivers_license_id); CREATE TABLE drivers_license ( - id INTEGER NOT NULL IDENTITY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY, license_number INTEGER NOT NULL ); CREATE UNIQUE INDEX drivers_license_license_number ON drivers_license(license_number); diff --git a/spring-test/src/test/resources/org/springframework/test/context/junit4/spr8849/spr8849-schema.sql b/spring-test/src/test/resources/org/springframework/test/context/junit4/spr8849/spr8849-schema.sql index da1ce4b8c98..2407ffa5edc 100644 --- a/spring-test/src/test/resources/org/springframework/test/context/junit4/spr8849/spr8849-schema.sql +++ b/spring-test/src/test/resources/org/springframework/test/context/junit4/spr8849/spr8849-schema.sql @@ -1,3 +1,3 @@ CREATE TABLE enigma ( - id INTEGER NOT NULL IDENTITY + id INTEGER GENERATED BY DEFAULT AS IDENTITY );