HHH-12368 - java.sql.SQLFeatureNotSupportedException in LobCreatorBuilderImpl

This commit is contained in:
Vlad Mihalcea 2018-10-12 11:31:44 +03:00
parent e9e6b0573f
commit a5138621a6
8 changed files with 80 additions and 4 deletions

View File

@ -116,7 +116,7 @@ ext {
jodaTime: "joda-time:joda-time:${jodaTimeVersion}",
informix: 'com.ibm.informix:jdbc:4.10.7.20160517',
informix: 'com.ibm.informix:jdbc:4.10.12',
jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
xapool: "com.experlog:xapool:1.5.0",
mockito: 'org.mockito:mockito-core:2.19.1',

View File

@ -1643,4 +1643,9 @@ public abstract class AbstractHANADialect extends Dialect {
public boolean supportsNoWait() {
return true;
}
@Override
public boolean supportsJdbcConnectionLobCreation(DatabaseMetaData databaseMetaData) {
return false;
}
}

View File

@ -11,6 +11,7 @@ import java.io.OutputStream;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.ResultSet;
@ -2957,6 +2958,18 @@ public abstract class Dialect implements ConversionContext {
return String.format( "\'%s\'", escapeLiteral( literal ) );
}
/**
* Check whether the JDBC {@link java.sql.Connection} supports creating LOBs via {@link Connection#createBlob()},
* {@link Connection#createNClob()} or {@link Connection#createClob()}.
*
* @param databaseMetaData JDBC {@link DatabaseMetaData} which can be used if LOB creation is supported only starting from a given Driver version
*
* @return {@code true} if LOBs can be created via the JDBC Connection.
*/
public boolean supportsJdbcConnectionLobCreation(DatabaseMetaData databaseMetaData) {
return true;
}
/**
* Escape String literal.
*

View File

@ -7,6 +7,7 @@
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@ -637,4 +638,9 @@ public class PostgreSQL81Dialect extends Dialect {
public boolean supportsNoWait() {
return true;
}
@Override
public boolean supportsJdbcConnectionLobCreation(DatabaseMetaData databaseMetaData) {
return false;
}
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.dialect;
import java.sql.DatabaseMetaData;
import java.sql.Types;
import org.hibernate.cfg.Environment;
@ -236,4 +237,9 @@ public class SAPDBDialect extends Dialect {
null
);
}
@Override
public boolean supportsJdbcConnectionLobCreation(DatabaseMetaData databaseMetaData) {
return false;
}
}

View File

@ -280,6 +280,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
this.typeInfoSet.addAll( TypeInfo.extractTypeInfo( databaseMetaData ) );
this.lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder(
dialect,
cfgService.getSettings(),
databaseMetaData.getConnection()
);

View File

@ -13,6 +13,7 @@ import java.sql.SQLException;
import java.util.Map;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.ContextualLobCreator;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
@ -46,12 +47,13 @@ public class LobCreatorBuilderImpl implements LobCreatorBuilder {
* The public factory method for obtaining the appropriate LOB creator (according to given
* JDBC {@link java.sql.Connection}).
*
* @param dialect The {@link Dialect} in use
* @param configValues The map of settings
* @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
* specifically for creating LOB references.
*/
public static LobCreatorBuilderImpl makeLobCreatorBuilder(Map configValues, Connection jdbcConnection) {
return new LobCreatorBuilderImpl( useContextualLobCreation( configValues, jdbcConnection ) );
public static LobCreatorBuilderImpl makeLobCreatorBuilder(Dialect dialect, Map configValues, Connection jdbcConnection) {
return new LobCreatorBuilderImpl( useContextualLobCreation( dialect, configValues, jdbcConnection ) );
}
/**
@ -73,12 +75,14 @@ public class LobCreatorBuilderImpl implements LobCreatorBuilder {
* but also whether the actual {@link java.sql.Connection} instance implements them (i.e. can be called without simply
* throwing an exception).
*
* @param dialect The {@link Dialect} in use
* @param configValues The map of settings
* @param jdbcConnection The connection which can be used in level-of-support testing.
*
* @return True if the connection can be used to create LOBs; false otherwise.
*/
@SuppressWarnings("unchecked")
private static boolean useContextualLobCreation(Map configValues, Connection jdbcConnection) {
private static boolean useContextualLobCreation(Dialect dialect, Map configValues, Connection jdbcConnection) {
final boolean isNonContextualLobCreationRequired =
ConfigurationHelper.getBoolean( Environment.NON_CONTEXTUAL_LOB_CREATION, configValues );
if ( isNonContextualLobCreationRequired ) {
@ -98,6 +102,10 @@ public class LobCreatorBuilderImpl implements LobCreatorBuilder {
LOG.disablingContextualLOBCreationSinceOldJdbcVersion( meta.getJDBCMajorVersion() );
return false;
}
if ( !dialect.supportsJdbcConnectionLobCreation( meta ) ) {
return false;
}
}
catch ( SQLException ignore ) {
// ignore exception and continue

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.engine.jdbc.env.internal;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.junit.Assert.assertFalse;
/**
* @author Vlad Mihalcea
*/
public class LobCreationCheckSkipTest extends BaseEntityManagerFunctionalTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger( CoreMessageLogger.class, LobCreatorBuilderImpl.class.getName()
) );
private Triggerable triggerable = logInspection.watchForLogMessages( "HHH000424:" );
@Test
public void test() {
assertFalse(triggerable.wasTriggered());
}
}