HHH-12059 HHH-11440 HHH-11286 HHH-10333 - hbm2ddl.auto=validate and hbm2ddl.auto=update do not work with Oracle and SQLServer when Jdbc driver Connection implementation does not implement getSchema()
This commit is contained in:
parent
ca92a3fe5b
commit
aaa8c65938
|
@ -743,6 +743,11 @@ public class Oracle8iDialect extends Dialect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentSchemaCommand() {
|
||||
return "SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') FROM DUAL";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartitionBy() {
|
||||
return true;
|
||||
|
|
|
@ -120,6 +120,11 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
return ']';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentSchemaCommand() {
|
||||
return "SELECT SCHEMA_NAME()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public char openQuote() {
|
||||
return '[';
|
||||
|
|
|
@ -28,52 +28,53 @@ public class DefaultSchemaNameResolver implements SchemaNameResolver {
|
|||
|
||||
public static final DefaultSchemaNameResolver INSTANCE = new DefaultSchemaNameResolver();
|
||||
|
||||
private final SchemaNameResolver delegate;
|
||||
private SchemaNameResolver delegate;
|
||||
|
||||
public DefaultSchemaNameResolver() {
|
||||
this.delegate = determineAppropriateResolverDelegate();
|
||||
private DefaultSchemaNameResolver() {
|
||||
}
|
||||
|
||||
private static SchemaNameResolver determineAppropriateResolverDelegate() {
|
||||
// unfortunately Connection#getSchema is only available in Java 1.7 and above
|
||||
// and Hibernate still baselines on 1.6. So for now, use reflection and
|
||||
// leverage the Connection#getSchema method if it is available.
|
||||
final Class<Connection> jdbcConnectionClass = Connection.class;
|
||||
try {
|
||||
final Method getSchemaMethod = jdbcConnectionClass.getMethod( "getSchema" );
|
||||
if ( getSchemaMethod != null ) {
|
||||
if ( getSchemaMethod.getReturnType().equals( String.class ) ) {
|
||||
return new SchemaNameResolverJava17Delegate( getSchemaMethod );
|
||||
private void determineAppropriateResolverDelegate(Connection connection) {
|
||||
if ( delegate == null ) {
|
||||
// unfortunately Connection#getSchema is only available in Java 1.7 and above
|
||||
// and Hibernate still baselines on 1.6. So for now, use reflection and
|
||||
// leverage the Connection#getSchema method if it is available.
|
||||
try {
|
||||
final Class<? extends Connection> jdbcConnectionClass = connection.getClass();
|
||||
final Method getSchemaMethod = jdbcConnectionClass.getMethod( "getSchema" );
|
||||
if ( getSchemaMethod != null && getSchemaMethod.getReturnType().equals( String.class ) ) {
|
||||
try {
|
||||
// If the JDBC driver does not implement the Java 7 spec, but the JRE is Java 7
|
||||
// then the getSchemaMethod is not null but the call to getSchema() throws an java.lang.AbstractMethodError
|
||||
connection.getSchema();
|
||||
delegate = new SchemaNameResolverJava17Delegate( );
|
||||
}
|
||||
catch (java.lang.AbstractMethodError e) {
|
||||
log.debugf( "Unable to use Java 1.7 Connection#getSchema" );
|
||||
delegate = SchemaNameResolverFallbackDelegate.INSTANCE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.debugf( "Unable to use Java 1.7 Connection#getSchema" );
|
||||
delegate = SchemaNameResolverFallbackDelegate.INSTANCE;
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
log.debugf( "Unable to resolve connection default schema : " + ignore.getMessage() );
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
log.debugf( "Unable to use Java 1.7 Connection#getSchema" );
|
||||
return SchemaNameResolverFallbackDelegate.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException {
|
||||
determineAppropriateResolverDelegate( connection );
|
||||
return delegate.resolveSchemaName( connection, dialect );
|
||||
}
|
||||
|
||||
public static class SchemaNameResolverJava17Delegate implements SchemaNameResolver {
|
||||
private final Method getSchemaMethod;
|
||||
|
||||
public SchemaNameResolverJava17Delegate(Method getSchemaMethod) {
|
||||
this.getSchemaMethod = getSchemaMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException {
|
||||
try {
|
||||
return (String) getSchemaMethod.invoke( connection );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unable to invoke Connection#getSchema method via reflection", e );
|
||||
}
|
||||
return connection.getSchema();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,29 +96,11 @@ public class DefaultSchemaNameResolver implements SchemaNameResolver {
|
|||
);
|
||||
}
|
||||
|
||||
final Statement statement = connection.createStatement();
|
||||
try {
|
||||
final ResultSet resultSet = statement.executeQuery( dialect.getCurrentSchemaCommand() );
|
||||
try {
|
||||
if ( !resultSet.next() ) {
|
||||
return null;
|
||||
}
|
||||
return resultSet.getString( 1 );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
resultSet.close();
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
try (
|
||||
final Statement statement = connection.createStatement();
|
||||
final ResultSet resultSet = statement.executeQuery( dialect.getCurrentSchemaCommand() )
|
||||
) {
|
||||
return resultSet.next() ? resultSet.getString( 1 ) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,7 +298,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
|||
return schemaNameResolver.resolveSchemaName( databaseMetaData.getConnection(), dialect );
|
||||
}
|
||||
catch (Exception e) {
|
||||
// for now, just ignore the exception.
|
||||
log.debug( "Unable to resolve connection default schema", e );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@ public interface SchemaNameResolver {
|
|||
*
|
||||
* @return The name of the schema (may be null).
|
||||
*/
|
||||
public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException;
|
||||
String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
*/
|
||||
package org.hibernate.tool.schema;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
|
@ -24,7 +27,7 @@ public enum JdbcMetadaAccessStrategy {
|
|||
* The {@link org.hibernate.tool.schema.spi.SchemaMigrator} and {@link org.hibernate.tool.schema.spi.SchemaValidator}
|
||||
* execute a single {@link java.sql.DatabaseMetaData#getTables(String, String, String, String[])} call
|
||||
* to retrieve all the database table in order to determine all the {@link javax.persistence.Entity} have a mapped database tables.
|
||||
*
|
||||
* <p>
|
||||
* This strategy is the default one and it may require {@link AvailableSettings#DEFAULT_CATALOG} and/or
|
||||
* {@link AvailableSettings#DEFAULT_SCHEMA} values to be provided.
|
||||
*/
|
||||
|
@ -41,20 +44,34 @@ public enum JdbcMetadaAccessStrategy {
|
|||
return strategy;
|
||||
}
|
||||
|
||||
public static JdbcMetadaAccessStrategy interpretHbm2ddlSetting(Object value) {
|
||||
if(value == null){
|
||||
return GROUPED;
|
||||
public static JdbcMetadaAccessStrategy interpretSetting(Map options) {
|
||||
if ( options == null ) {
|
||||
return interpretHbm2ddlSetting( null );
|
||||
}
|
||||
String name = value.toString();
|
||||
if ( StringHelper.isEmpty( name ) || GROUPED.strategy.equals( name ) ) {
|
||||
return GROUPED;
|
||||
}
|
||||
else if ( INDIVIDUALLY.strategy.equals( name ) ) {
|
||||
else if ( ConfigurationHelper.getBoolean( AvailableSettings.ENABLE_SYNONYMS, options, false ) ) {
|
||||
// Use of synonyms can cause issues during schema validation or schema update when GROUPED strategy is used (especially in Oracle)
|
||||
return INDIVIDUALLY;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException( "Unrecognized `" + AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY + "` value : " + name );
|
||||
return interpretHbm2ddlSetting( options.get( AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static JdbcMetadaAccessStrategy interpretHbm2ddlSetting(Object value) {
|
||||
if ( value == null ) {
|
||||
return GROUPED;
|
||||
}
|
||||
else {
|
||||
final String name = value.toString();
|
||||
if ( StringHelper.isEmpty( name ) || GROUPED.strategy.equals( name ) ) {
|
||||
return GROUPED;
|
||||
}
|
||||
else if ( INDIVIDUALLY.strategy.equals( name ) ) {
|
||||
return INDIVIDUALLY;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException( "Unrecognized `" + AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY + "` value : " + name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,10 +104,7 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv
|
|||
}
|
||||
|
||||
private JdbcMetadaAccessStrategy determineJdbcMetadaAccessStrategy(Map options) {
|
||||
if ( options == null ) {
|
||||
return JdbcMetadaAccessStrategy.interpretHbm2ddlSetting( null );
|
||||
}
|
||||
return JdbcMetadaAccessStrategy.interpretHbm2ddlSetting( options.get( AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY ) );
|
||||
return JdbcMetadaAccessStrategy.interpretSetting( options );
|
||||
}
|
||||
|
||||
GenerationTarget[] buildGenerationTargets(
|
||||
|
|
Loading…
Reference in New Issue