Browse Source

Consistent incrementer arrangement for PostgreSQL, DB2 and SAP HANA

Includes related polishing in core.metadata and datasource.embedded and a revision of the corresponding database definitions in sql-error-codes.

Issue: SPR-16558
pull/1716/merge
Juergen Hoeller 8 years ago
parent
commit
82515a3f01
  1. 23
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java
  2. 3
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/Db2CallMetaDataProvider.java
  3. 4
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyCallMetaDataProvider.java
  4. 8
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java
  5. 2
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java
  6. 6
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java
  7. 3
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/HanaCallMetaDataProvider.java
  8. 3
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/HsqlTableMetaDataProvider.java
  9. 12
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java
  10. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java
  11. 10
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java
  12. 7
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java
  13. 21
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java
  14. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java
  15. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java
  16. 9
      spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java
  17. 9
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.java
  18. 17
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.java
  19. 56
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/Db2LuwMaxValueIncrementer.java
  20. 56
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/Db2MainframeMaxValueIncrementer.java
  21. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java
  22. 54
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HanaSequenceMaxValueIncrementer.java
  23. 12
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlSequenceMaxValueIncrementer.java
  24. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/OracleSequenceMaxValueIncrementer.java
  25. 18
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.java
  26. 55
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgresSequenceMaxValueIncrementer.java
  27. 11
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java
  28. 8
      spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java
  29. 95
      spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml
  30. 59
      spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java

23
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -67,7 +67,7 @@ public class CallMetaDataProviderFactory {
*/ */
static public CallMetaDataProvider createMetaDataProvider(DataSource dataSource, final CallMetaDataContext context) { static public CallMetaDataProvider createMetaDataProvider(DataSource dataSource, final CallMetaDataContext context) {
try { try {
CallMetaDataProvider result = (CallMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, databaseMetaData -> { return (CallMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, databaseMetaData -> {
String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
boolean accessProcedureColumnMetaData = context.isAccessCallParameterMetaData(); boolean accessProcedureColumnMetaData = context.isAccessCallParameterMetaData();
if (context.isFunction()) { if (context.isFunction()) {
@ -94,31 +94,33 @@ public class CallMetaDataProviderFactory {
} }
} }
} }
CallMetaDataProvider provider; CallMetaDataProvider provider;
if ("Oracle".equals(databaseProductName)) { if ("Oracle".equals(databaseProductName)) {
provider = new OracleCallMetaDataProvider(databaseMetaData); provider = new OracleCallMetaDataProvider(databaseMetaData);
} }
else if ("DB2".equals(databaseProductName)) { else if ("PostgreSQL".equals(databaseProductName)) {
provider = new Db2CallMetaDataProvider((databaseMetaData)); provider = new PostgresCallMetaDataProvider((databaseMetaData));
} }
else if ("Apache Derby".equals(databaseProductName)) { else if ("Apache Derby".equals(databaseProductName)) {
provider = new DerbyCallMetaDataProvider((databaseMetaData)); provider = new DerbyCallMetaDataProvider((databaseMetaData));
} }
else if ("PostgreSQL".equals(databaseProductName)) { else if ("DB2".equals(databaseProductName)) {
provider = new PostgresCallMetaDataProvider((databaseMetaData)); provider = new Db2CallMetaDataProvider((databaseMetaData));
} }
else if ("Sybase".equals(databaseProductName)) { else if ("HDB".equals(databaseProductName)) {
provider = new SybaseCallMetaDataProvider((databaseMetaData)); provider = new HanaCallMetaDataProvider((databaseMetaData));
} }
else if ("Microsoft SQL Server".equals(databaseProductName)) { else if ("Microsoft SQL Server".equals(databaseProductName)) {
provider = new SqlServerCallMetaDataProvider((databaseMetaData)); provider = new SqlServerCallMetaDataProvider((databaseMetaData));
} }
else if ("HDB".equals(databaseProductName)) { else if ("Sybase".equals(databaseProductName)) {
provider = new HanaCallMetaDataProvider((databaseMetaData)); provider = new SybaseCallMetaDataProvider((databaseMetaData));
} }
else { else {
provider = new GenericCallMetaDataProvider(databaseMetaData); provider = new GenericCallMetaDataProvider(databaseMetaData);
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Using " + provider.getClass().getName()); logger.debug("Using " + provider.getClass().getName());
} }
@ -129,7 +131,6 @@ public class CallMetaDataProviderFactory {
} }
return provider; return provider;
}); });
return result;
} }
catch (MetaDataAccessException ex) { catch (MetaDataAccessException ex) {
throw new DataAccessResourceFailureException("Error retrieving database metadata", ex); throw new DataAccessResourceFailureException("Error retrieving database metadata", ex);

3
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/Db2CallMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -70,6 +70,7 @@ public class Db2CallMetaDataProvider extends GenericCallMetaDataProvider {
if (schemaName != null) { if (schemaName != null) {
return super.metaDataSchemaNameToUse(schemaName); return super.metaDataSchemaNameToUse(schemaName);
} }
// Use current user schema if no schema specified... // Use current user schema if no schema specified...
String userName = getUserName(); String userName = getUserName();
return (userName != null ? userName.toUpperCase() : null); return (userName != null ? userName.toUpperCase() : null);

4
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyCallMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,12 +35,14 @@ public class DerbyCallMetaDataProvider extends GenericCallMetaDataProvider {
super(databaseMetaData); super(databaseMetaData);
} }
@Override @Override
@Nullable @Nullable
public String metaDataSchemaNameToUse(@Nullable String schemaName) { public String metaDataSchemaNameToUse(@Nullable String schemaName) {
if (schemaName != null) { if (schemaName != null) {
return super.metaDataSchemaNameToUse(schemaName); return super.metaDataSchemaNameToUse(schemaName);
} }
// Use current user schema if no schema specified... // Use current user schema if no schema specified...
String userName = getUserName(); String userName = getUserName();
return (userName != null ? userName.toUpperCase() : null); return (userName != null ? userName.toUpperCase() : null);

8
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,9 +20,8 @@ import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
/** /**
* The Derby specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * The Derby specific implementation of {@link TableMetaDataProvider}.
* Overrides the Derby metadata info regarding retrieving generated keys. It seems to work OK so not sure why * Overrides the Derby metadata info regarding retrieving generated keys.
* they claim it's not supported.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 3.0 * @since 3.0
@ -53,4 +52,5 @@ public class DerbyTableMetaDataProvider extends GenericTableMetaDataProvider {
public boolean isGetGeneratedKeysSupported() { public boolean isGetGeneratedKeysSupported() {
return (super.isGetGeneratedKeysSupported() || this.supportsGeneratedKeysOverride); return (super.isGetGeneratedKeysSupported() || this.supportsGeneratedKeysOverride);
} }
} }

2
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java

@ -34,7 +34,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* Generic implementation for the {@link CallMetaDataProvider} interface. * A generic implementation of the {@link CallMetaDataProvider} interface.
* This class can be extended to provide database specific behavior. * This class can be extended to provide database specific behavior.
* *
* @author Thomas Risberg * @author Thomas Risberg

6
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,8 +34,8 @@ import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* A generic implementation of the {@link TableMetaDataProvider} that should provide * A generic implementation of the {@link TableMetaDataProvider} interface
* enough features for all supported databases. * which should provide enough features for all supported databases.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Juergen Hoeller * @author Juergen Hoeller

3
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/HanaCallMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@ public class HanaCallMetaDataProvider extends GenericCallMetaDataProvider {
super(databaseMetaData); super(databaseMetaData);
} }
@Override @Override
public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
super.initializeWithMetaData(databaseMetaData); super.initializeWithMetaData(databaseMetaData);

3
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/HsqlTableMetaDataProvider.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@ public class HsqlTableMetaDataProvider extends GenericTableMetaDataProvider {
super(databaseMetaData); super(databaseMetaData);
} }
@Override @Override
public boolean isGetGeneratedKeysSimulated() { public boolean isGetGeneratedKeysSimulated() {
return true; return true;

12
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java

@ -50,12 +50,10 @@ public class TableMetaDataProviderFactory {
JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData(); boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData();
TableMetaDataProvider provider; TableMetaDataProvider provider;
if ("Oracle".equals(databaseProductName)) { if ("Oracle".equals(databaseProductName)) {
provider = new OracleTableMetaDataProvider(databaseMetaData, provider = new OracleTableMetaDataProvider(
context.isOverrideIncludeSynonymsDefault()); databaseMetaData, context.isOverrideIncludeSynonymsDefault());
}
else if ("HSQL Database Engine".equals(databaseProductName)) {
provider = new HsqlTableMetaDataProvider(databaseMetaData);
} }
else if ("PostgreSQL".equals(databaseProductName)) { else if ("PostgreSQL".equals(databaseProductName)) {
provider = new PostgresTableMetaDataProvider(databaseMetaData); provider = new PostgresTableMetaDataProvider(databaseMetaData);
@ -63,9 +61,13 @@ public class TableMetaDataProviderFactory {
else if ("Apache Derby".equals(databaseProductName)) { else if ("Apache Derby".equals(databaseProductName)) {
provider = new DerbyTableMetaDataProvider(databaseMetaData); provider = new DerbyTableMetaDataProvider(databaseMetaData);
} }
else if ("HSQL Database Engine".equals(databaseProductName)) {
provider = new HsqlTableMetaDataProvider(databaseMetaData);
}
else { else {
provider = new GenericTableMetaDataProvider(databaseMetaData); provider = new GenericTableMetaDataProvider(databaseMetaData);
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Using " + provider.getClass().getSimpleName()); logger.debug("Using " + provider.getClass().getSimpleName());
} }

5
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,7 +24,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/** /**
* Base class for {@link EmbeddedDatabaseConfigurer} implementations providing common shutdown behavior. * Base class for {@link EmbeddedDatabaseConfigurer} implementations
* providing common shutdown behavior through a "SHUTDOWN" statement.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Juergen Hoeller * @author Juergen Hoeller

10
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,7 +26,8 @@ import org.apache.derby.jdbc.EmbeddedDriver;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* {@link EmbeddedDatabaseConfigurer} for the Apache Derby database 10.6+. * {@link EmbeddedDatabaseConfigurer} for the Apache Derby database.
*
* <p>Call {@link #getInstance()} to get the singleton instance of this class. * <p>Call {@link #getInstance()} to get the singleton instance of this class.
* *
* @author Oliver Gierke * @author Oliver Gierke
@ -43,10 +44,9 @@ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigure
/** /**
* Get the singleton {@link DerbyEmbeddedDatabaseConfigurer} instance. * Get the singleton {@link DerbyEmbeddedDatabaseConfigurer} instance.
* @return the configurer * @return the configurer instance
* @throws ClassNotFoundException if Derby is not on the classpath
*/ */
public static synchronized DerbyEmbeddedDatabaseConfigurer getInstance() throws ClassNotFoundException { public static synchronized DerbyEmbeddedDatabaseConfigurer getInstance() {
if (instance == null) { if (instance == null) {
// disable log file // disable log file
System.setProperty("derby.stream.error.method", System.setProperty("derby.stream.error.method",

7
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,8 +30,7 @@ import javax.sql.DataSource;
public interface EmbeddedDatabaseConfigurer { public interface EmbeddedDatabaseConfigurer {
/** /**
* Configure the properties required to create and connect to the embedded * Configure the properties required to create and connect to the embedded database.
* database instance.
* @param properties connection properties to configure * @param properties connection properties to configure
* @param databaseName the name of the embedded database * @param databaseName the name of the embedded database
*/ */
@ -39,7 +38,7 @@ public interface EmbeddedDatabaseConfigurer {
/** /**
* Shut down the embedded database instance that backs the supplied {@link DataSource}. * Shut down the embedded database instance that backs the supplied {@link DataSource}.
* @param dataSource the data source * @param dataSource the corresponding {@link DataSource}
* @param databaseName the name of the database being shut down * @param databaseName the name of the database being shut down
*/ */
void shutdown(DataSource dataSource, String databaseName); void shutdown(DataSource dataSource, String databaseName);

21
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,8 +19,8 @@ package org.springframework.jdbc.datasource.embedded;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Maps well-known {@linkplain EmbeddedDatabaseType embedded database types} to * Maps well-known {@linkplain EmbeddedDatabaseType embedded database types}
* {@link EmbeddedDatabaseConfigurer} strategies. * to {@link EmbeddedDatabaseConfigurer} strategies.
* *
* @author Keith Donald * @author Keith Donald
* @author Oliver Gierke * @author Oliver Gierke
@ -29,6 +29,12 @@ import org.springframework.util.Assert;
*/ */
final class EmbeddedDatabaseConfigurerFactory { final class EmbeddedDatabaseConfigurerFactory {
/**
* Return a configurer instance for the given embedded database type.
* @param type HSQL, H2 or Derby
* @return the configurer instance
* @throws IllegalStateException if the driver for the specified database type is not available
*/
public static EmbeddedDatabaseConfigurer getConfigurer(EmbeddedDatabaseType type) throws IllegalStateException { public static EmbeddedDatabaseConfigurer getConfigurer(EmbeddedDatabaseType type) throws IllegalStateException {
Assert.notNull(type, "EmbeddedDatabaseType is required"); Assert.notNull(type, "EmbeddedDatabaseType is required");
try { try {
@ -43,14 +49,9 @@ final class EmbeddedDatabaseConfigurerFactory {
throw new UnsupportedOperationException("Embedded database type [" + type + "] is not supported"); throw new UnsupportedOperationException("Embedded database type [" + type + "] is not supported");
} }
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException | NoClassDefFoundError ex) {
throw new IllegalStateException("Driver for test database type [" + type + throw new IllegalStateException("Driver for test database type [" + type + "] is not available", ex);
"] is not available in the classpath", ex);
}
} }
private EmbeddedDatabaseConfigurerFactory() {
/* no-op */
} }
} }

5
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import org.springframework.util.ClassUtils;
/** /**
* {@link EmbeddedDatabaseConfigurer} for an H2 embedded database instance. * {@link EmbeddedDatabaseConfigurer} for an H2 embedded database instance.
*
* <p>Call {@link #getInstance()} to get the singleton instance of this class. * <p>Call {@link #getInstance()} to get the singleton instance of this class.
* *
* @author Oliver Gierke * @author Oliver Gierke
@ -40,7 +41,7 @@ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigu
/** /**
* Get the singleton {@code H2EmbeddedDatabaseConfigurer} instance. * Get the singleton {@code H2EmbeddedDatabaseConfigurer} instance.
* @return the configurer * @return the configurer instance
* @throws ClassNotFoundException if H2 is not on the classpath * @throws ClassNotFoundException if H2 is not on the classpath
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

5
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import org.springframework.util.ClassUtils;
/** /**
* {@link EmbeddedDatabaseConfigurer} for an HSQL embedded database instance. * {@link EmbeddedDatabaseConfigurer} for an HSQL embedded database instance.
*
* <p>Call {@link #getInstance()} to get the singleton instance of this class. * <p>Call {@link #getInstance()} to get the singleton instance of this class.
* *
* @author Keith Donald * @author Keith Donald
@ -39,7 +40,7 @@ final class HsqlEmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfi
/** /**
* Get the singleton {@link HsqlEmbeddedDatabaseConfigurer} instance. * Get the singleton {@link HsqlEmbeddedDatabaseConfigurer} instance.
* @return the configurer * @return the configurer instance
* @throws ClassNotFoundException if HSQL is not on the classpath * @throws ClassNotFoundException if HSQL is not on the classpath
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

9
spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java

@ -406,9 +406,10 @@ public abstract class JdbcUtils {
} }
/** /**
* Extract a common name for the database in use even if various drivers/platforms provide varying names. * Extract a common name for the target database in use even if
* various drivers/platforms provide varying names at runtime.
* @param source the name as provided in database metadata * @param source the name as provided in database metadata
* @return the common name to be used * @return the common name to be used (e.g. "DB2" or "Sybase")
*/ */
@Nullable @Nullable
public static String commonDatabaseName(@Nullable String source) { public static String commonDatabaseName(@Nullable String source) {
@ -431,10 +432,10 @@ public abstract class JdbcUtils {
* @return whether the type is numeric * @return whether the type is numeric
*/ */
public static boolean isNumeric(int sqlType) { public static boolean isNumeric(int sqlType) {
return Types.BIT == sqlType || Types.BIGINT == sqlType || Types.DECIMAL == sqlType || return (Types.BIT == sqlType || Types.BIGINT == sqlType || Types.DECIMAL == sqlType ||
Types.DOUBLE == sqlType || Types.FLOAT == sqlType || Types.INTEGER == sqlType || Types.DOUBLE == sqlType || Types.FLOAT == sqlType || Types.INTEGER == sqlType ||
Types.NUMERIC == sqlType || Types.REAL == sqlType || Types.SMALLINT == sqlType || Types.NUMERIC == sqlType || Types.REAL == sqlType || Types.SMALLINT == sqlType ||
Types.TINYINT == sqlType; Types.TINYINT == sqlType);
} }
/** /**

9
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.java

@ -19,13 +19,16 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given sequence * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* on DB2/390 or DB2/400. Thanks to Jens Eickmeyer for the suggestion! * of a given sequence on DB2 for the mainframe (z/OS, DB2/390, DB2/400).
*
* <p>Thanks to Jens Eickmeyer for the suggestion!
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 2.5.3 * @since 2.5.3
* @see DB2SequenceMaxValueIncrementer * @deprecated in favor of the differently named {@link Db2MainframeMaxValueIncrementer}
*/ */
@Deprecated
public class DB2MainframeSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { public class DB2MainframeSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
/** /**

17
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.java

@ -19,14 +19,17 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given sequence * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* on DB2 UDB (for Unix and Windows). Thanks to Mark MacMahon for the suggestion! * of a given sequence on DB2 LUW (for Linux, Unix and Windows).
*
* <p>Thanks to Mark MacMahon for the suggestion!
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 1.1.3 * @since 1.1.3
* @see DB2MainframeSequenceMaxValueIncrementer * @deprecated in favor of the specifically named {@link Db2LuwMaxValueIncrementer}
*/ */
public class DB2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { @Deprecated
public class DB2SequenceMaxValueIncrementer extends Db2LuwMaxValueIncrementer {
/** /**
* Default constructor for bean property style usage. * Default constructor for bean property style usage.
@ -45,10 +48,4 @@ public class DB2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncr
super(dataSource, incrementerName); super(dataSource, incrementerName);
} }
@Override
protected String getSequenceQuery() {
return "values nextval for " + getIncrementerName();
}
} }

56
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/Db2LuwMaxValueIncrementer.java

@ -0,0 +1,56 @@
/*
* Copyright 2002-2018 the original author 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
*
* http://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 javax.sql.DataSource;
/**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given sequence on DB2 LUW (for Linux, Unix and Windows).
*
* <p>Thanks to Mark MacMahon for the suggestion!
*
* @author Juergen Hoeller
* @since 4.3.15
* @see Db2MainframeMaxValueIncrementer
*/
public class Db2LuwMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
/**
* Default constructor for bean property style usage.
* @see #setDataSource
* @see #setIncrementerName
*/
public Db2LuwMaxValueIncrementer() {
}
/**
* Convenience constructor.
* @param dataSource the DataSource to use
* @param incrementerName the name of the sequence/table to use
*/
public Db2LuwMaxValueIncrementer(DataSource dataSource, String incrementerName) {
super(dataSource, incrementerName);
}
@Override
protected String getSequenceQuery() {
return "values nextval for " + getIncrementerName();
}
}

56
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/Db2MainframeMaxValueIncrementer.java

@ -0,0 +1,56 @@
/*
* Copyright 2002-2018 the original author 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
*
* http://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 javax.sql.DataSource;
/**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given sequence on DB2 for the mainframe (z/OS, DB2/390, DB2/400).
*
* <p>Thanks to Jens Eickmeyer for the suggestion!
*
* @author Juergen Hoeller
* @since 4.3.15
* @see Db2LuwMaxValueIncrementer
*/
public class Db2MainframeMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
/**
* Default constructor for bean property style usage.
* @see #setDataSource
* @see #setIncrementerName
*/
public Db2MainframeMaxValueIncrementer() {
}
/**
* Convenience constructor.
* @param dataSource the DataSource to use
* @param incrementerName the name of the sequence/table to use
*/
public Db2MainframeMaxValueIncrementer(DataSource dataSource, String incrementerName) {
super(dataSource, incrementerName);
}
@Override
protected String getSequenceQuery() {
return "select next value for " + getIncrementerName() + " from sysibm.sysdummy1";
}
}

5
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,7 +19,8 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given H2 Database sequence. * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given H2 sequence.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 2.5 * @since 2.5

54
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HanaSequenceMaxValueIncrementer.java

@ -0,0 +1,54 @@
/*
* Copyright 2002-2018 the original author 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
*
* http://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 javax.sql.DataSource;
/**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given SAP HANA sequence.
*
* @author Jonathan Bregler
* @author Juergen Hoeller
* @since 4.3.15
*/
public class HanaSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
/**
* Default constructor for bean property style usage.
* @see #setDataSource
* @see #setIncrementerName
*/
public HanaSequenceMaxValueIncrementer() {
}
/**
* Convenience constructor.
* @param dataSource the DataSource to use
* @param incrementerName the name of the sequence/table to use
*/
public HanaSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
super(dataSource, incrementerName);
}
@Override
protected String getSequenceQuery() {
return "select " + getIncrementerName() + ".nextval from dummy";
}
}

12
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlSequenceMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,11 +19,13 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given HSQL sequence. * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* Thanks to Guillaume Bilodeau for the suggestion! * of a given HSQL sequence.
* *
* <p><b>NOTE:</b> This is an alternative to using a regular table to support generating * <p>Thanks to Guillaume Bilodeau for the suggestion!
* unique keys that was necessary in previous versions of HSQL. *
* <p><b>NOTE:</b> This is an alternative to using a regular table to support
* generating unique keys that was necessary in previous versions of HSQL.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 2.5 * @since 2.5

5
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/OracleSequenceMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,7 +19,8 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given Oracle sequence. * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given Oracle sequence.
* *
* @author Dmitriy Kopylenko * @author Dmitriy Kopylenko
* @author Thomas Risberg * @author Thomas Risberg

18
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,12 +19,16 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given PostgreSQL sequence. * {@link DataFieldMaxValueIncrementer} that retrieves the next value
* Thanks to Tomislav Urban for the suggestion! * of a given PostgreSQL sequence.
*
* <p>Thanks to Tomislav Urban for the suggestion!
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @deprecated in favor of the differently named {@link PostgresSequenceMaxValueIncrementer}
*/ */
public class PostgreSQLSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { @Deprecated
public class PostgreSQLSequenceMaxValueIncrementer extends PostgresSequenceMaxValueIncrementer {
/** /**
* Default constructor for bean property style usage. * Default constructor for bean property style usage.
@ -43,10 +47,4 @@ public class PostgreSQLSequenceMaxValueIncrementer extends AbstractSequenceMaxVa
super(dataSource, incrementerName); super(dataSource, incrementerName);
} }
@Override
protected String getSequenceQuery() {
return "select nextval('" + getIncrementerName() + "')";
}
} }

55
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgresSequenceMaxValueIncrementer.java

@ -0,0 +1,55 @@
/*
* Copyright 2002-2018 the original author 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
*
* http://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 javax.sql.DataSource;
/**
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
* of a given PostgreSQL sequence.
*
* <p>Thanks to Tomislav Urban for the suggestion!
*
* @author Juergen Hoeller
* @since 4.3.15
*/
public class PostgresSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
/**
* Default constructor for bean property style usage.
* @see #setDataSource
* @see #setIncrementerName
*/
public PostgresSequenceMaxValueIncrementer() {
}
/**
* Convenience constructor.
* @param dataSource the DataSource to use
* @param incrementerName the name of the sequence/table to use
*/
public PostgresSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
super(dataSource, incrementerName);
}
@Override
protected String getSequenceQuery() {
return "select nextval('" + getIncrementerName() + "')";
}
}

11
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,8 +19,7 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource; import javax.sql.DataSource;
/** /**
* {@link DataFieldMaxValueIncrementer} that increments * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given Sybase table
* the maximum value of a given Sybase SQL Anywhere table
* with the equivalent of an auto-increment column. Note: If you use this class, your table key * with the equivalent of an auto-increment column. Note: If you use this class, your table key
* column should <i>NOT</i> be defined as an IDENTITY column, as the sequence table does the job. * column should <i>NOT</i> be defined as an IDENTITY column, as the sequence table does the job.
* *
@ -40,9 +39,9 @@ import javax.sql.DataSource;
* is rolled back, the unused values will never be served. The maximum hole size in * is rolled back, the unused values will never be served. The maximum hole size in
* numbering is consequently the value of cacheSize. * numbering is consequently the value of cacheSize.
* *
* <b>HINT:</b> Since Sybase Anywhere supports the JDBC 3.0 {@code getGeneratedKeys} method, * <b>HINT:</b> Since Sybase Anywhere supports the JDBC 3.0 {@code getGeneratedKeys}
* it is recommended to use IDENTITY columns directly in the tables and then using a * method, it is recommended to use IDENTITY columns directly in the tables and then
* {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing * using a {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing
* a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the
* {@code update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)} * {@code update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)}
* method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * method of the {@link org.springframework.jdbc.core.JdbcTemplate}.

8
spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,9 +39,9 @@ import javax.sql.DataSource;
* is rolled back, the unused values will never be served. The maximum hole size in * is rolled back, the unused values will never be served. The maximum hole size in
* numbering is consequently the value of cacheSize. * numbering is consequently the value of cacheSize.
* *
* <b>HINT:</b> Since Sybase supports the JDBC 3.0 {@code getGeneratedKeys} method, * <b>HINT:</b> Since Sybase Adaptive Server supports the JDBC 3.0 {@code getGeneratedKeys}
* it is recommended to use IDENTITY columns directly in the tables and then using a * method, it is recommended to use IDENTITY columns directly in the tables and then
* {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing * using a {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing
* a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the
* {@code update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)} * {@code update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)}
* method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * method of the {@link org.springframework.jdbc.core.JdbcTemplate}.

95
spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml

@ -14,7 +14,7 @@
--> -->
<beans> <beans>
<bean id="DB2" class="org.springframework.jdbc.support.SQLErrorCodes"> <bean id="DB2" name="Db2" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName"> <property name="databaseProductName">
<value>DB2*</value> <value>DB2*</value>
</property> </property>
@ -83,7 +83,49 @@
</property> </property>
</bean> </bean>
<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes"> <!-- http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm -->
<bean id="HDB" name="Hana" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductNames">
<list>
<value>SAP HANA</value>
<value>SAP DB</value>
</list>
</property>
<property name="badSqlGrammarCodes">
<value>
257,259,260,261,262,263,264,267,268,269,270,271,272,273,275,276,277,278,
278,279,280,281,282,283,284,285,286,288,289,290,294,295,296,297,299,308,309,
313,315,316,318,319,320,321,322,323,324,328,329,330,333,335,336,337,338,340,
343,350,351,352,362,368
</value>
</property>
<property name="permissionDeniedCodes">
<value>10,258</value>
</property>
<property name="duplicateKeyCodes">
<value>301</value>
</property>
<property name="dataIntegrityViolationCodes">
<value>461,462</value>
</property>
<property name="dataAccessResourceFailureCodes">
<value>-813,-709,-708,1024,1025,1026,1027,1029,1030,1031</value>
</property>
<property name="invalidResultSetAccessCodes">
<value>-11210,582,587,588,594</value>
</property>
<property name="cannotAcquireLockCodes">
<value>131</value>
</property>
<property name="cannotSerializeTransactionCodes">
<value>138,143</value>
</property>
<property name="deadlockLoserCodes">
<value>133</value>
</property>
</bean>
<bean id="HSQL" name="Hsql" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName"> <property name="databaseProductName">
<value>HSQL Database Engine</value> <value>HSQL Database Engine</value>
</property> </property>
@ -116,7 +158,7 @@
</property> </property>
</bean> </bean>
<bean id="MS-SQL" class="org.springframework.jdbc.support.SQLErrorCodes"> <bean id="MS-SQL" name="SqlServer" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName"> <property name="databaseProductName">
<value>Microsoft SQL Server</value> <value>Microsoft SQL Server</value>
</property> </property>
@ -191,7 +233,7 @@
</property> </property>
</bean> </bean>
<bean id="PostgreSQL" class="org.springframework.jdbc.support.SQLErrorCodes"> <bean id="PostgreSQL" name="Postgres" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="useSqlStateForTranslation"> <property name="useSqlStateForTranslation">
<value>true</value> <value>true</value>
</property> </property>
@ -222,9 +264,9 @@
<property name="databaseProductNames"> <property name="databaseProductNames">
<list> <list>
<value>Sybase SQL Server</value> <value>Sybase SQL Server</value>
<value>SQL Server</value>
<value>Adaptive Server Enterprise</value> <value>Adaptive Server Enterprise</value>
<value>ASE</value> <!-- name as returned by jTDS driver --> <value>ASE</value> <!-- name as returned by jTDS driver -->
<value>SQL Server</value>
<value>sql server</value> <!-- name as returned by jTDS driver --> <value>sql server</value> <!-- name as returned by jTDS driver -->
</list> </list>
</property> </property>
@ -248,47 +290,4 @@
</property> </property>
</bean> </bean>
<!-- http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm -->
<bean id="Hana" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductNames">
<list>
<value>SAP DB</value>
<value>HDB</value>
</list>
</property>
<property name="badSqlGrammarCodes">
<value>
257,259,260,261,262,263,264,267,268,269,270,271,272,273,275,276,277,278,
278,279,280,281,282,283,284,285,286,288,289,290,294,295,296,297,299,308,309,
313,315,316,318,319,320,321,322,323,324,328,329,330,333,335,336,337,338,340,
343,350,351,352,362,368
</value>
</property>
<property name="permissionDeniedCodes">
<value>10,258</value>
</property>
<property name="duplicateKeyCodes">
<value>301</value>
</property>
<property name="dataIntegrityViolationCodes">
<value>461,462</value>
</property>
<property name="dataAccessResourceFailureCodes">
<value>-813,-709,-708,1024,1025,1026,1027,1029,1030,1031</value>
</property>
<property name="invalidResultSetAccessCodes">
<value>-11210,582,587,588,594</value>
</property>
<property name="cannotAcquireLockCodes">
<value>131</value>
</property>
<property name="cannotSerializeTransactionCodes">
<value>138,143</value>
</property>
<property name="deadlockLoserCodes">
<value>133</value>
</property>
</bean>
</beans> </beans>

59
spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,10 +24,11 @@ import javax.sql.DataSource;
import org.junit.Test; import org.junit.Test;
import org.springframework.jdbc.support.incrementer.HanaSequenceMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.PostgreSQLSequenceMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.PostgresSequenceMaxValueIncrementer;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*; import static org.mockito.BDDMockito.*;
@ -38,15 +39,37 @@ import static org.mockito.BDDMockito.*;
*/ */
public class DataFieldMaxValueIncrementerTests { public class DataFieldMaxValueIncrementerTests {
private DataSource dataSource = mock(DataSource.class); private final DataSource dataSource = mock(DataSource.class);
private Connection connection = mock(Connection.class); private final Connection connection = mock(Connection.class);
private Statement statement = mock(Statement.class); private final Statement statement = mock(Statement.class);
private ResultSet resultSet = mock(ResultSet.class); private final ResultSet resultSet = mock(ResultSet.class);
@Test
public void testHanaSequenceMaxValueIncrementer() throws SQLException {
given(dataSource.getConnection()).willReturn(connection);
given(connection.createStatement()).willReturn(statement);
given(statement.executeQuery("select myseq.nextval from dummy")).willReturn(resultSet);
given(resultSet.next()).willReturn(true);
given(resultSet.getLong(1)).willReturn(10L, 12L);
HanaSequenceMaxValueIncrementer incrementer = new HanaSequenceMaxValueIncrementer();
incrementer.setDataSource(dataSource);
incrementer.setIncrementerName("myseq");
incrementer.setPaddingLength(2);
incrementer.afterPropertiesSet();
assertEquals(10, incrementer.nextLongValue());
assertEquals("12", incrementer.nextStringValue());
verify(resultSet, times(2)).close();
verify(statement, times(2)).close();
verify(connection, times(2)).close();
}
@Test @Test
public void testHsqlMaxValueIncrementer() throws SQLException { public void testHsqlMaxValueIncrementer() throws SQLException {
given(dataSource.getConnection()).willReturn(connection); given(dataSource.getConnection()).willReturn(connection);
@ -136,21 +159,21 @@ public class DataFieldMaxValueIncrementerTests {
} }
@Test @Test
public void testPostgreSQLSequenceMaxValueIncrementer() throws SQLException { public void testOracleSequenceMaxValueIncrementer() throws SQLException {
given(dataSource.getConnection()).willReturn(connection); given(dataSource.getConnection()).willReturn(connection);
given(connection.createStatement()).willReturn(statement); given(connection.createStatement()).willReturn(statement);
given(statement.executeQuery("select nextval('myseq')")).willReturn(resultSet); given(statement.executeQuery("select myseq.nextval from dual")).willReturn(resultSet);
given(resultSet.next()).willReturn(true); given(resultSet.next()).willReturn(true);
given(resultSet.getLong(1)).willReturn(10L, 12L); given(resultSet.getLong(1)).willReturn(10L, 12L);
PostgreSQLSequenceMaxValueIncrementer incrementer = new PostgreSQLSequenceMaxValueIncrementer(); OracleSequenceMaxValueIncrementer incrementer = new OracleSequenceMaxValueIncrementer();
incrementer.setDataSource(dataSource); incrementer.setDataSource(dataSource);
incrementer.setIncrementerName("myseq"); incrementer.setIncrementerName("myseq");
incrementer.setPaddingLength(5); incrementer.setPaddingLength(2);
incrementer.afterPropertiesSet(); incrementer.afterPropertiesSet();
assertEquals("00010", incrementer.nextStringValue()); assertEquals(10, incrementer.nextLongValue());
assertEquals(12, incrementer.nextIntValue()); assertEquals("12", incrementer.nextStringValue());
verify(resultSet, times(2)).close(); verify(resultSet, times(2)).close();
verify(statement, times(2)).close(); verify(statement, times(2)).close();
@ -158,21 +181,21 @@ public class DataFieldMaxValueIncrementerTests {
} }
@Test @Test
public void testOracleSequenceMaxValueIncrementer() throws SQLException { public void testPostgresSequenceMaxValueIncrementer() throws SQLException {
given(dataSource.getConnection()).willReturn(connection); given(dataSource.getConnection()).willReturn(connection);
given(connection.createStatement()).willReturn(statement); given(connection.createStatement()).willReturn(statement);
given(statement.executeQuery("select myseq.nextval from dual")).willReturn(resultSet); given(statement.executeQuery("select nextval('myseq')")).willReturn(resultSet);
given(resultSet.next()).willReturn(true); given(resultSet.next()).willReturn(true);
given(resultSet.getLong(1)).willReturn(10L, 12L); given(resultSet.getLong(1)).willReturn(10L, 12L);
OracleSequenceMaxValueIncrementer incrementer = new OracleSequenceMaxValueIncrementer(); PostgresSequenceMaxValueIncrementer incrementer = new PostgresSequenceMaxValueIncrementer();
incrementer.setDataSource(dataSource); incrementer.setDataSource(dataSource);
incrementer.setIncrementerName("myseq"); incrementer.setIncrementerName("myseq");
incrementer.setPaddingLength(2); incrementer.setPaddingLength(5);
incrementer.afterPropertiesSet(); incrementer.afterPropertiesSet();
assertEquals(10, incrementer.nextLongValue()); assertEquals("00010", incrementer.nextStringValue());
assertEquals("12", incrementer.nextStringValue()); assertEquals(12, incrementer.nextIntValue());
verify(resultSet, times(2)).close(); verify(resultSet, times(2)).close();
verify(statement, times(2)).close(); verify(statement, times(2)).close();

Loading…
Cancel
Save