diff --git a/.gitignore b/.gitignore index 2f7896d..7bcda54 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ target/ +.flattened-pom.xml +pom.xml.releaseBackup +release.properties + diff --git a/.travis.yml b/.travis.yml index fb30873..eb18c74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ sudo: false language: java jdk: - - openjdk8 - openjdk11 + - openjdk17 services: - postgresql diff --git a/README.md b/README.md index 5342262..9db7be6 100644 --- a/README.md +++ b/README.md @@ -38,15 +38,7 @@ You can use this sequence generator like this ```java @Id -@GenericGenerator( - name = "some_column_name_id_generator", - strategy = "com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator", - parameters = { - @Parameter(name = "sequence", value = "SOME_SEQUENCE_NAME"), - @Parameter(name = "fetch_size", value = "SOME_FETCH_SIZE_VALUE") - }) -@GeneratedValue(generator = "some_column_name_id_generator") -@Column(name = "SOME_COLUMN_NAME") +@BatchSequence(name = "SOME_SEQUENCE_NAME", fetch_size = SOME_FETCH_SIZE_VALUE) private Long someColumnName; ``` @@ -56,11 +48,7 @@ You need to configure the following things
SOME_SEQUENCE_NAME
the SQL name of the sequence from which the values should be fetched
SOME_FETCH_SIZE_VALUE
-
integer, how many values should be fetched at once, this should be equal to the CACHE value of the sequence
-
SOME_COLUMN_NAME
-
the SQL name of the column for which the value should be generated
-
some_column_name_id_generator
-
unique if of the generator
+
integer, how many values should be fetched at once, this should be equal to the CACHE value of the sequence, optional, default value is 10
diff --git a/pom.xml b/pom.xml index 1d6a48a..a7740ee 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.github.marschall hibernate-batch-sequence-generator - 1.1.1-SNAPSHOT + 2.2.1-SNAPSHOT 2017 https://github.com/marschall/hibernate-batch-sequence-generator Hibernate Batch Sequence Generator @@ -37,7 +37,7 @@ ${project.url} HEAD - + GitHub Issues https://github.com/marschall/hibernate-batch-sequence-generator/issues @@ -61,22 +61,56 @@ maven-compiler-plugin - ${javac.target} - ${javac.target} - ${javac.target} + 11 + 17 + + org.codehaus.mojo + flatten-maven-plugin + + ossrh + + + + + flatten + process-resources + + flatten + + + + + flatten.clean + clean + + clean + + + + maven-javadoc-plugin - https://docs.oracle.com/javase/8/docs/api/ - https://docs.jboss.org/hibernate/orm/5.6/javadocs/ + https://docs.oracle.com/javase/11/docs/api/ + https://docs.jboss.org/hibernate/orm/6.4/javadocs/ + true + + + attach-javadocs + package + + jar + + + - org.jboss.jandex + io.smallrye jandex-maven-plugin @@ -110,60 +144,65 @@ maven-clean-plugin - 3.1.0 + 3.3.2 maven-compiler-plugin - 3.8.1 + 3.12.1 maven-deploy-plugin - 2.8.2 + 3.1.1 + + + org.codehaus.mojo + flatten-maven-plugin + 1.6.0 maven-gpg-plugin - 3.0.1 + 3.1.0 maven-install-plugin - 2.5.2 + 3.1.1 maven-site-plugin - 3.9.1 + 3.12.1 maven-surefire-plugin - 2.22.2 + 3.2.5 maven-jar-plugin - 3.1.1 + 3.3.0 maven-javadoc-plugin - 3.3.1 + 3.6.3 - org.jboss.jandex + io.smallrye jandex-maven-plugin - 1.2.1 + 3.1.6 maven-resources-plugin - 3.2.0 + 3.3.1 maven-scm-plugin - 1.12.0 + 2.0.1 maven-source-plugin - 3.2.1 + 3.3.0 maven-release-plugin - 2.5.3 + 3.0.1 @@ -174,28 +213,28 @@ org.junit junit-bom - 5.8.1 + 5.10.2 pom import org.springframework spring-framework-bom - 5.3.12 + 6.1.10 pom import com.oracle.database.jdbc ojdbc-bom - 21.3.0.0 + 23.4.0.24.05 pom import org.apache.logging.log4j log4j-bom - 2.14.1 + 2.23.1 pom import @@ -204,11 +243,17 @@ - org.hibernate + org.hibernate.orm hibernate-core ${hibernate.version} provided + + org.hibernate.orm + hibernate-community-dialects + ${hibernate.version} + provided + org.junit.jupiter @@ -228,55 +273,61 @@ net.ttddyy datasource-proxy - 1.7 + 1.10 test org.hsqldb hsqldb - 2.5.1 + 2.7.3 test org.postgresql postgresql - 42.3.0 + 42.7.3 test com.h2database h2 - 1.4.200 + 2.2.224 test com.microsoft.sqlserver mssql-jdbc - 9.4.0.jre8 + 12.6.1.jre11 test org.firebirdsql.jdbc jaybird - 4.0.4.java8 + 5.0.5.java11 test org.mariadb.jdbc mariadb-java-client - 2.7.4 + 3.4.0 test + + + org.slf4j + jcl-over-slf4j + + com.oracle.database.jdbc - ojdbc8 + ojdbc11 test com.ibm.db2 jcc - 11.5.6.0 + 11.5.9.0 test @@ -288,7 +339,7 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-slf4j2-impl test @@ -303,6 +354,12 @@ org.springframework spring-context test + + + org.springframework + spring-jcl + + org.springframework @@ -352,10 +409,10 @@ - 1.8 utf-8 utf-8 - 5.6.0.Final + 6.5.2.Final + 2024-06-21T15:45:22Z diff --git a/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequence.java b/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequence.java new file mode 100644 index 0000000..eec455b --- /dev/null +++ b/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequence.java @@ -0,0 +1,34 @@ +package com.github.marschall.hibernate.batchsequencegenerator; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.hibernate.annotations.IdGeneratorType; + +/** + * Meta annotation to use {@link BatchSequenceGenerator} as an identifier generator. + */ +@IdGeneratorType(BatchSequenceGenerator.class) +@Retention(RUNTIME) +@Target({ FIELD, METHOD }) +public @interface BatchSequence { + + /** + * Returns the name of the sequence to use. + * + * @return the name of the sequence to use + */ + String name(); + + /** + * Returns how many sequence values to fetch at once. + * + * @return how many sequence values to fetch at once, must be positive + */ + int fetchSize() default BatchSequenceGenerator.DEFAULT_FETCH_SIZE; + +} diff --git a/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGenerator.java b/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGenerator.java index 295621f..8ce68b4 100644 --- a/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGenerator.java +++ b/src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGenerator.java @@ -3,6 +3,7 @@ import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; +import java.math.RoundingMode; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -17,15 +18,16 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.model.relational.ExportableProducer; import org.hibernate.boot.model.relational.QualifiedNameParser; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.BulkInsertionCapableIdentifierGenerator; -import org.hibernate.id.Configurable; import org.hibernate.id.IdentifierGenerationException; -import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.enhanced.DatabaseStructure; import org.hibernate.id.enhanced.SequenceStructure; import org.hibernate.internal.util.config.ConfigurationHelper; @@ -36,26 +38,23 @@ * A sequence generator that uses a recursive query to fetch multiple * values from a sequence in a single database access. * - *

Parameters

- * The following configuration parameters are supported: - *
- *
{@value #SEQUENCE_PARAM}
- *
mandatory, name of the sequence to use
- *
{@value #FETCH_SIZE_PARAM}
- *
optional, how many sequence numbers should be fetched at a time, - * default is {@value #DEFAULT_FETCH_SIZE}
- *
+ *

Configuration

+ *

+ * @Id
+ * @BatchSequence(name = "SOME_SEQUENCE_NAME", fetch_size = SOME_FETCH_SIZE_VALUE)
+ * private Long someColumnName;
+ * 
* *

SQL

* Per default the generated SELECT will look something like this *

- * WITH RECURSIVE t(n, level_num) AS (
- *   SELECT nextval(seq_xxx) as n, 1 as level_num
+ * WITH RECURSIVE t(n) AS (
+ *   SELECT 1
  *     UNION ALL
- *   SELECT nextval(seq_xxx) as n, level_num + 1 as level_num
+ *   SELECT n + 1
  *   FROM t
- *   WHERE level_num < ?)
- * SELECT n
+ *   WHERE n < ?)
+ * SELECT nextval(seq_xxx)
  *   FROM t;
  * 
* @@ -132,16 +131,22 @@ * In theory any RDBMS that supports {@code WITH RECURSIVE} and * sequences is supported. */ -public class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGenerator, PersistentIdentifierGenerator, Configurable { +public final class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGenerator, IdentifierGenerator, ExportableProducer { /** * Indicates the name of the sequence to use, mandatory. + * + * @deprecated use {@link BatchSequence} */ + @Deprecated public static final String SEQUENCE_PARAM = "sequence"; /** * Indicates how many sequence values to fetch at once. The default value is {@link #DEFAULT_FETCH_SIZE}. + * + * @deprecated use {@link BatchSequence} */ + @Deprecated public static final String FETCH_SIZE_PARAM = "fetch_size"; /** @@ -150,32 +155,47 @@ public class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGen public static final int DEFAULT_FETCH_SIZE = 10; private final Lock lock = new ReentrantLock(); + private final BatchSequence annotation; private String select; private int fetchSize; private IdentifierPool identifierPool; private IdentifierExtractor identifierExtractor; private DatabaseStructure databaseStructure; + + public BatchSequenceGenerator(BatchSequence annotation) { + this.annotation = annotation; + } + + public BatchSequenceGenerator() { + this.annotation = null; + } @Override - public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) - throws MappingException { + public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) { JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class); Dialect dialect = jdbcEnvironment.getDialect(); - String sequenceName = determineSequenceName(params); - this.fetchSize = determineFetchSize(params); + String sequenceName; + if (this.annotation != null) { + sequenceName = this.annotation.name(); + this.fetchSize = this.annotation.fetchSize(); + } else { + sequenceName = determineSequenceName(params); + this.fetchSize = determineFetchSize(params); + } this.select = buildSelect(sequenceName, dialect); - this.identifierExtractor = IdentifierExtractor.getIdentifierExtractor(type.getReturnedClass()); + Class returnedClass = type.getReturnedClass(); + this.identifierExtractor = IdentifierExtractor.getIdentifierExtractor(returnedClass); this.identifierPool = IdentifierPool.empty(); - this.databaseStructure = this.buildDatabaseStructure(type, sequenceName, jdbcEnvironment); + this.databaseStructure = this.buildDatabaseStructure(type, sequenceName, jdbcEnvironment, params); } private static String buildSelect(String sequenceName, Dialect dialect) { - if (dialect instanceof org.hibernate.dialect.Oracle8iDialect) { - return "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " FROM dual CONNECT BY rownum <= ?"; + if (dialect instanceof org.hibernate.dialect.OracleDialect) { + return "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " FROM dual CONNECT BY rownum <= ?"; } if (dialect instanceof org.hibernate.dialect.SQLServerDialect) { // No RECURSIVE @@ -184,7 +204,7 @@ private static String buildSelect(String sequenceName, Dialect dialect) { + "UNION ALL " +"SELECT n + 1 as n FROM t WHERE n < ?) " // sequence generation outside of WITH - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n FROM t"; + + "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " as n FROM t"; } if (dialect instanceof org.hibernate.dialect.DB2Dialect) { // No RECURSIVE @@ -195,37 +215,42 @@ private static String buildSelect(String sequenceName, Dialect dialect) { + "UNION ALL " +"SELECT n + 1 as n FROM t WHERE n < ?) " // sequence generation outside of WITH - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n FROM t"; + + "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " as n FROM t"; } if (dialect instanceof org.hibernate.dialect.HSQLDialect) { // https://stackoverflow.com/questions/44472280/cte-based-sequence-generation-with-hsqldb/52329862 - return "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " FROM UNNEST(SEQUENCE_ARRAY(1, ?, 1))"; + return "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " FROM UNNEST(SEQUENCE_ARRAY(1, ?, 1))"; } - if (dialect instanceof org.hibernate.dialect.FirebirdDialect) { + if (dialect instanceof org.hibernate.community.dialect.FirebirdDialect) { return "WITH RECURSIVE t(n, level_num) AS (" - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n, 1 as level_num " + + "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " as n, 1 as level_num " // difference + " FROM rdb$database " + "UNION ALL " - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n, level_num + 1 as level_num " + + "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " as n, level_num + 1 as level_num " + " FROM t " + " WHERE level_num < ?) " + "SELECT n FROM t"; } - return "WITH RECURSIVE t(n, level_num) AS (" - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n, 1 as level_num " + return "WITH RECURSIVE t(n) AS (" + + "SELECT 1 " + "UNION ALL " - + "SELECT " + dialect.getSelectSequenceNextValString(sequenceName) + " as n, level_num + 1 as level_num " + + "SELECT n + 1 " + " FROM t " - + " WHERE level_num < ?) " - + "SELECT n FROM t"; + + " WHERE n < ?) " + + "SELECT " + dialect.getSequenceSupport().getSelectSequenceNextValString(sequenceName) + " FROM t"; } - private SequenceStructure buildDatabaseStructure(Type type, String sequenceName, JdbcEnvironment jdbcEnvironment) { - return new SequenceStructure(jdbcEnvironment, + private SequenceStructure buildDatabaseStructure(Type type, String sequenceName, JdbcEnvironment jdbcEnvironment, Properties params) { + return new SequenceStructure(jdbcEnvironment, this.determineContributor(params), QualifiedNameParser.INSTANCE.parse(sequenceName), 1, 1, type.getReturnedClass()); } + private String determineContributor(Properties params) { + final String contributor = params.getProperty( IdentifierGenerator.CONTRIBUTOR_NAME ); + return contributor == null ? "orm" : contributor; + } + private static String determineSequenceName(Properties params) { String sequenceName = params.getProperty(SEQUENCE_PARAM); if (sequenceName == null) { @@ -248,12 +273,17 @@ public boolean supportsBulkInsertionIdentifierGeneration() { } @Override - public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect dialect) { - return dialect.getSelectSequenceNextValString(this.getSequenceName()); + public boolean supportsJdbcBatchInserts() { + return true; } @Override - public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { + public String determineBulkInsertionIdentifierGenerationSelectFragment(SqlStringGenerationContext context) { + return context.getDialect().getSequenceSupport().getSelectSequenceNextValString(this.getSequenceName()); + } + + @Override + public Serializable generate(SharedSessionContractImplementor session, Object object) { this.lock.lock(); try { if (this.identifierPool.isEmpty()) { @@ -265,25 +295,8 @@ public Serializable generate(SharedSessionContractImplementor session, Object ob } } - @Override - public Object generatorKey() { - return this.getSequenceName(); - } - private String getSequenceName() { - return this.databaseStructure.getName(); - } - - @Override - @Deprecated - public String[] sqlCreateStrings(Dialect dialect) { - return this.databaseStructure.sqlCreateStrings(dialect); - } - - @Override - @Deprecated - public String[] sqlDropStrings(Dialect dialect) { - return this.databaseStructure.sqlDropStrings(dialect); + return this.databaseStructure.getPhysicalName().getObjectName().getCanonicalName(); } @Override @@ -298,7 +311,7 @@ private IdentifierPool replenishIdentifierPool(SharedSessionContractImplementor try (PreparedStatement statement = coordinator.getStatementPreparer().prepareStatement(this.select)) { statement.setFetchSize(this.fetchSize); statement.setInt(1, this.fetchSize); - try (ResultSet resultSet = coordinator.getResultSetReturn().extract(statement)) { + try (ResultSet resultSet = coordinator.getResultSetReturn().extract(statement, this.select)) { while (resultSet.next()) { identifiers.add(this.identifierExtractor.extractIdentifier(resultSet)); } @@ -348,55 +361,55 @@ Serializable next() { * * @see org.hibernate.id.IntegralDataTypeHolder */ - enum IdentifierExtractor { - - INTEGER_IDENTIFIER_EXTRACTOR { - @Override - Serializable extractIdentifier(ResultSet resultSet) throws SQLException { - int intValue = resultSet.getInt(1); - if (resultSet.wasNull()) { - throw new IdentifierGenerationException("sequence returned null"); - } - return intValue; + @FunctionalInterface + interface IdentifierExtractor { + + IdentifierExtractor SHORT_IDENTIFIER_EXTRACTOR = (ResultSet resultSet) -> { + short shortValue = resultSet.getShort(1); + if (resultSet.wasNull()) { + throw new IdentifierGenerationException("sequence returned null"); } - }, - - LONG_IDENTIFIER_EXTRACTOR { - @Override - Serializable extractIdentifier(ResultSet resultSet) throws SQLException { - long longValue = resultSet.getLong(1); - if (resultSet.wasNull()) { - throw new IdentifierGenerationException("sequence returned null"); - } - return longValue; + return shortValue; + }; + + IdentifierExtractor INTEGER_IDENTIFIER_EXTRACTOR = (ResultSet resultSet) -> { + int intValue = resultSet.getInt(1); + if (resultSet.wasNull()) { + throw new IdentifierGenerationException("sequence returned null"); } - }, - - BIG_INTEGER_IDENTIFIER_EXTRACTOR { - @Override - Serializable extractIdentifier(ResultSet resultSet) throws SQLException { - BigDecimal bigDecimal = resultSet.getBigDecimal(1); - if (resultSet.wasNull()) { - throw new IdentifierGenerationException("sequence returned null"); - } - return bigDecimal.setScale(0, BigDecimal.ROUND_UNNECESSARY).toBigInteger(); + return intValue; + }; + + IdentifierExtractor LONG_IDENTIFIER_EXTRACTOR = (ResultSet resultSet) -> { + long longValue = resultSet.getLong(1); + if (resultSet.wasNull()) { + throw new IdentifierGenerationException("sequence returned null"); } - }, - - BIG_DECIMAL_IDENTIFIER_EXTRACTOR { - @Override - Serializable extractIdentifier(ResultSet resultSet) throws SQLException { - BigDecimal bigDecimal = resultSet.getBigDecimal(1); - if (resultSet.wasNull()) { - throw new IdentifierGenerationException("sequence returned null"); - } - return bigDecimal; + return longValue; + }; + + IdentifierExtractor BIG_INTEGER_IDENTIFIER_EXTRACTOR = (ResultSet resultSet) -> { + BigDecimal bigDecimal = resultSet.getBigDecimal(1); + if (resultSet.wasNull()) { + throw new IdentifierGenerationException("sequence returned null"); } + return bigDecimal.setScale(0, RoundingMode.UNNECESSARY).toBigInteger(); }; - abstract Serializable extractIdentifier(ResultSet resultSet) throws SQLException; + IdentifierExtractor BIG_DECIMAL_IDENTIFIER_EXTRACTOR = (ResultSet resultSet) -> { + BigDecimal bigDecimal = resultSet.getBigDecimal(1); + if (resultSet.wasNull()) { + throw new IdentifierGenerationException("sequence returned null"); + } + return bigDecimal; + }; + + Serializable extractIdentifier(ResultSet resultSet) throws SQLException; static IdentifierExtractor getIdentifierExtractor(Class integralType) { + if ((integralType == Short.class) || (integralType == short.class)) { + return SHORT_IDENTIFIER_EXTRACTOR; + } if ((integralType == Integer.class) || (integralType == int.class)) { return INTEGER_IDENTIFIER_EXTRACTOR; } diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGeneratorIntegrationTest.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGeneratorIntegrationTest.java index a4fc3c1..c34479d 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGeneratorIntegrationTest.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGeneratorIntegrationTest.java @@ -1,6 +1,5 @@ package com.github.marschall.hibernate.batchsequencegenerator; -import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.sql.Connection; @@ -9,8 +8,6 @@ import java.util.List; import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.junit.jupiter.params.ParameterizedTest; @@ -27,7 +24,6 @@ import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionTemplate; -import com.github.marschall.hibernate.batchsequencegenerator.configurations.Db2Configuration; import com.github.marschall.hibernate.batchsequencegenerator.configurations.FirebirdConfiguration; import com.github.marschall.hibernate.batchsequencegenerator.configurations.H2Configuration; import com.github.marschall.hibernate.batchsequencegenerator.configurations.HibernateConfiguration; @@ -40,18 +36,19 @@ import com.github.marschall.hibernate.batchsequencegenerator.entities.ChildEntity; import com.github.marschall.hibernate.batchsequencegenerator.entities.ParentEntity; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; + public class BatchSequenceGeneratorIntegrationTest { private AnnotationConfigApplicationContext applicationContext; private TransactionTemplate template; - - public static List parameters() { List parameters = new ArrayList<>(); - parameters.add(Arguments.of(Db2Configuration.class, "db2-default")); - parameters.add(Arguments.of(Db2Configuration.class, "db2-batched")); +// parameters.add(Arguments.of(Db2Configuration.class, "db2-default")); +// parameters.add(Arguments.of(Db2Configuration.class, "db2-batched")); parameters.add(Arguments.of(MariaDbConfiguration.class, "maria-default")); parameters.add(Arguments.of(MariaDbConfiguration.class, "maria-batched")); parameters.add(Arguments.of(FirebirdConfiguration.class, "firebird-default")); @@ -77,7 +74,7 @@ private void setUp(Class dataSourceConfiguration, String persistenceUnitName) this.applicationContext.register(dataSourceConfiguration, HibernateConfiguration.class, TransactionManagerConfiguration.class); ConfigurableEnvironment environment = this.applicationContext.getEnvironment(); MutablePropertySources propertySources = environment.getPropertySources(); - Map source = singletonMap(HibernateConfiguration.PERSISTENCE_UNIT_NAME, persistenceUnitName); + Map source = Map.of(HibernateConfiguration.PERSISTENCE_UNIT_NAME, persistenceUnitName); propertySources.addFirst(new MapPropertySource("persistence unit name", source)); this.applicationContext.refresh(); diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/Travis.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/Travis.java index e98018b..eb7a6a1 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/Travis.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/Travis.java @@ -1,11 +1,9 @@ package com.github.marschall.hibernate.batchsequencegenerator; -import org.aopalliance.aop.AspectException; - public final class Travis { private Travis() { - throw new AspectException("not instantiable"); + throw new AssertionError("not instantiable"); } public static boolean isTravis() { diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/HibernateConfiguration.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/HibernateConfiguration.java index cfe043b..f4cf7c8 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/HibernateConfiguration.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/HibernateConfiguration.java @@ -26,10 +26,12 @@ public class HibernateConfiguration { @Bean public LocalContainerEntityManagerFactoryBean entityManager() { LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean(); - bean.setPersistenceUnitName(environment.getProperty(PERSISTENCE_UNIT_NAME)); - bean.setJpaDialect(jpaDialect()); + bean.setPersistenceUnitName(this.environment.getProperty(PERSISTENCE_UNIT_NAME)); + bean.setJpaDialect(this.jpaDialect()); bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - bean.setDataSource(dataSource); +// Map jpaProperties = Map.of(AvailableSettings.PHYSICAL_NAMING_STRATEGY, new CamelCaseToUnderscoresNamingStrategy()); +// bean.setJpaPropertyMap(jpaProperties); + bean.setDataSource(this.dataSource); return bean; } diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/OracleConfiguration.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/OracleConfiguration.java index 02b7db6..e6b886a 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/OracleConfiguration.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/OracleConfiguration.java @@ -11,6 +11,8 @@ import org.springframework.jdbc.datasource.init.DatabasePopulator; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import oracle.jdbc.OracleConnection; + @Configuration public class OracleConfiguration { @@ -19,11 +21,11 @@ public DataSource dataSource() { oracle.jdbc.OracleDriver.isDebug(); SingleConnectionDataSource dataSource = new SingleConnectionDataSource(); dataSource.setSuppressClose(true); - dataSource.setUrl("jdbc:oracle:thin:@localhost:1521/ORCLPDB1"); + dataSource.setUrl("jdbc:oracle:thin:@localhost:1521/FREEPDB1"); dataSource.setUsername("jdbc"); dataSource.setPassword("Cent-Quick-Space-Bath-8"); Properties connectionProperties = new Properties(); - connectionProperties.setProperty("oracle.net.disableOob", "true"); + connectionProperties.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_DISABLE_OUT_OF_BAND_BREAK, "true"); dataSource.setConnectionProperties(connectionProperties); return dataSource; } diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/SqlServerConfiguration.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/SqlServerConfiguration.java index 245f02e..e102a6d 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/SqlServerConfiguration.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/SqlServerConfiguration.java @@ -29,7 +29,7 @@ public DataSource dataSource() { SingleConnectionDataSource dataSource = new SingleConnectionDataSource(); dataSource.setSuppressClose(true); // https://github.com/microsoft/mssql-jdbc/issues/1182 - dataSource.setUrl("jdbc:sqlserver://localhost:1433;databaseName=master;sendTimeAsDatetime=false"); + dataSource.setUrl("jdbc:sqlserver://localhost:1433;databaseName=master;sendTimeAsDatetime=false;encrypt=false"); dataSource.setUsername("sa"); dataSource.setPassword("Cent-Quick-Space-Bath-8"); return dataSource; diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/TransactionManagerConfiguration.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/TransactionManagerConfiguration.java index 1c299fe..8d64549 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/TransactionManagerConfiguration.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/TransactionManagerConfiguration.java @@ -1,6 +1,5 @@ package com.github.marschall.hibernate.batchsequencegenerator.configurations; -import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; @@ -11,6 +10,8 @@ import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; +import jakarta.persistence.EntityManagerFactory; + @Configuration public class TransactionManagerConfiguration { @@ -28,7 +29,7 @@ public PlatformTransactionManager txManager(EntityManagerFactory emf) { JpaTransactionManager transactionManager = new JpaTransactionManager(emf); transactionManager.setDataSource(this.dataSource); transactionManager.setJpaDialect(this.jpaDialect); - transactionManager.setPersistenceUnitName(environment.getProperty(HibernateConfiguration.PERSISTENCE_UNIT_NAME)); + transactionManager.setPersistenceUnitName(this.environment.getProperty(HibernateConfiguration.PERSISTENCE_UNIT_NAME)); return transactionManager; } diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ChildEntity.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ChildEntity.java index dbf9172..4daa707 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ChildEntity.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ChildEntity.java @@ -3,14 +3,14 @@ import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.FETCH_SIZE_PARAM; import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.SEQUENCE_PARAM; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + @Entity(name = "CHILD_ENTITY") public class ChildEntity { @@ -30,7 +30,7 @@ public class ChildEntity { private Long parentId; public Long getChildId() { - return childId; + return this.childId; } public void setChildId(Long childId) { @@ -38,7 +38,7 @@ public void setChildId(Long childId) { } public Long getParentId() { - return parentId; + return this.parentId; } public void setParentId(Long parentId) { diff --git a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ParentEntity.java b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ParentEntity.java index 64d63be..71dbd91 100644 --- a/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ParentEntity.java +++ b/src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ParentEntity.java @@ -1,33 +1,21 @@ package com.github.marschall.hibernate.batchsequencegenerator.entities; -import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.FETCH_SIZE_PARAM; -import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.SEQUENCE_PARAM; - import java.util.HashSet; import java.util.Set; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; +import com.github.marschall.hibernate.batchsequencegenerator.BatchSequence; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Parameter; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; @Entity(name = "PARENT_ENTITY") public class ParentEntity { @Id - @GenericGenerator( - name = "parent_id_generator", - strategy = "com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator", - parameters = { - @Parameter(name = SEQUENCE_PARAM, value = "SEQ_PARENT_ID"), - @Parameter(name = FETCH_SIZE_PARAM, value = "50") - }) - @GeneratedValue(generator = "parent_id_generator") + @BatchSequence(name = "SEQ_PARENT_ID", fetchSize = 50) @Column(name = "PARENT_ID") private Long parentId; diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index ad45d7d..8d451b5 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -1,7 +1,8 @@ - + org.hibernate.jpa.HibernatePersistenceProvider @@ -9,9 +10,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -21,7 +19,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -35,9 +32,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -47,7 +41,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -61,9 +54,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -73,7 +63,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -87,9 +76,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -99,7 +85,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -113,9 +98,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -125,7 +107,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -139,9 +120,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -151,7 +129,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -165,9 +142,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -177,7 +151,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - @@ -191,9 +164,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ParentEntity com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - - - @@ -203,7 +173,6 @@ com.github.marschall.hibernate.batchsequencegenerators.entities.ChildEntity - diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml index f1dd62a..463e117 100644 --- a/src/test/resources/log4j2-test.xml +++ b/src/test/resources/log4j2-test.xml @@ -9,8 +9,6 @@ - - - + \ No newline at end of file diff --git a/src/test/resources/oracle/01_users.sql b/src/test/resources/oracle/01_users.sql index 6c92372..f36974c 100644 --- a/src/test/resources/oracle/01_users.sql +++ b/src/test/resources/oracle/01_users.sql @@ -1,4 +1,4 @@ -ALTER SESSION SET CONTAINER = ORCLPDB1; +ALTER SESSION SET CONTAINER = FREEPDB1; CREATE USER jdbc IDENTIFIED BY "Cent-Quick-Space-Bath-8"; diff --git a/src/test/resources/oracle/02_permissions.sql b/src/test/resources/oracle/02_permissions.sql index 7faa98b..8ef5169 100644 --- a/src/test/resources/oracle/02_permissions.sql +++ b/src/test/resources/oracle/02_permissions.sql @@ -1,5 +1,5 @@ -ALTER SESSION SET CONTAINER = ORCLPDB1; +ALTER SESSION SET CONTAINER = FREEPDB1; GRANT CONNECT TO jdbc CONTAINER=CURRENT; GRANT CREATE SESSION TO jdbc CONTAINER=CURRENT; diff --git a/src/test/resources/run_db2.sh b/src/test/resources/run_db2.sh index 9e3a9b9..12cee8c 100755 --- a/src/test/resources/run_db2.sh +++ b/src/test/resources/run_db2.sh @@ -11,4 +11,4 @@ docker run -itd --name jdbc-db2 \ -e 'DB2INST1_PASSWORD=Cent-Quick-Space-Bath-8' \ -e DBNAME=jdbc \ -e ARCHIVE_LOGS=false \ - ibmcom/db2:11.5.6.0a + ibmcom/db2:11.5.7.0 diff --git a/src/test/resources/run_firebird.sh b/src/test/resources/run_firebird.sh index 1b7b7ef..f5ccf68 100755 --- a/src/test/resources/run_firebird.sh +++ b/src/test/resources/run_firebird.sh @@ -9,4 +9,4 @@ docker run --name jdbc-firebird \ -e 'FIREBIRD_PASSWORD=Cent-Quick-Space-Bath-8' \ -p 3050:3050 \ --mount type=tmpfs,destination=/firebird/data \ - -d jacobalberty/firebird:v3.0.7 \ No newline at end of file + -d jacobalberty/firebird:v4.0.1 \ No newline at end of file diff --git a/src/test/resources/run_mariadb.sh b/src/test/resources/run_mariadb.sh index acef0a3..1c97bfd 100755 --- a/src/test/resources/run_mariadb.sh +++ b/src/test/resources/run_mariadb.sh @@ -10,4 +10,4 @@ docker run --name jdbc-mariadb \ -p 3307:3306 \ --mount type=tmpfs,destination=/var/lib/mysql \ -v ${DIRECTORY}/mariadb:/docker-entrypoint-initdb.d \ - -d mariadb:10.6.4 + -d mariadb:11.2.2 diff --git a/src/test/resources/run_oracle.sh b/src/test/resources/run_oracle.sh index b41b48d..a8fd2c2 100755 --- a/src/test/resources/run_oracle.sh +++ b/src/test/resources/run_oracle.sh @@ -3,8 +3,8 @@ DIRECTORY=`dirname $0` DIRECTORY=$(realpath $DIRECTORY) -docker run --name jdbc-oracle \ +docker run --name jdbc-oracle-23 \ -p 1521:1521 -p 5500:5500 \ --shm-size=1g \ -v ${DIRECTORY}/oracle:/docker-entrypoint-initdb.d/setup \ - -d oracle/database:19.3.0-se2 + -d oracle/database:23.4.0-free diff --git a/src/test/resources/run_postgres.sh b/src/test/resources/run_postgres.sh index 062ef64..9cf579c 100755 --- a/src/test/resources/run_postgres.sh +++ b/src/test/resources/run_postgres.sh @@ -5,4 +5,4 @@ docker run --name jdbc-postgres \ -e POSTGRES_USER=$USER \ -p 5432:5432 \ --mount type=tmpfs,destination=/var/lib/postgresql/data \ - -d postgres:14.0-alpine + -d postgres:16.1-alpine diff --git a/src/test/resources/run_sql_server.sh b/src/test/resources/run_sql_server.sh index 4267193..b2e1afb 100755 --- a/src/test/resources/run_sql_server.sh +++ b/src/test/resources/run_sql_server.sh @@ -6,4 +6,4 @@ docker run --name jdbc-sqlserver \ -e 'ACCEPT_EULA=Y' \ -e 'SA_PASSWORD=Cent-Quick-Space-Bath-8' \ -p 1433:1433 \ - -d mcr.microsoft.com/mssql/server:2019-latest + -d mcr.microsoft.com/mssql/server:2022-latest