/*
 * 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.internal;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Map;

import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.ContextualLobCreator;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;

import org.jboss.logging.Logger;

Builds LobCreator instances based on the capabilities of the environment.
Author:Steve Ebersole
/** * Builds {@link LobCreator} instances based on the capabilities of the environment. * * @author Steve Ebersole */
public class LobCreatorBuilder { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, LobCreatorBuilder.class.getName() ); private boolean useContextualLobCreation;
The public factory method for obtaining the appropriate (according to given JDBC Connection.
Params:
  • configValues – The map of settings
  • jdbcConnection – A JDBC Connection which can be used to gauge the drivers level of support, specifically for creating LOB references.
/** * The public factory method for obtaining the appropriate (according to given JDBC {@link java.sql.Connection}. * * @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 LobCreatorBuilder(Map configValues, Connection jdbcConnection) { this.useContextualLobCreation = useContextualLobCreation( configValues, jdbcConnection ); } private static final Class[] NO_ARG_SIG = new Class[0]; private static final Object[] NO_ARGS = new Object[0];
Basically here we are simply checking whether we can call the Connection methods for LOB creation added in JDBC 4. We not only check whether the Connection declares these methods, but also whether the actual Connection instance implements them (i.e. can be called without simply throwing an exception).
Params:
  • jdbcConnection – The connection which can be used in level-of-support testing.
Returns:True if the connection can be used to create LOBs; false otherwise.
/** * Basically here we are simply checking whether we can call the {@link Connection} methods for * LOB creation added in JDBC 4. We not only check whether the {@link Connection} declares these methods, * but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply * throwing an exception). * * @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) { final boolean isNonContextualLobCreationRequired = ConfigurationHelper.getBoolean( Environment.NON_CONTEXTUAL_LOB_CREATION, configValues ); if ( isNonContextualLobCreationRequired ) { LOG.disablingContextualLOBCreation( Environment.NON_CONTEXTUAL_LOB_CREATION ); return false; } if ( jdbcConnection == null ) { LOG.disablingContextualLOBCreationSinceConnectionNull(); return false; } try { try { final DatabaseMetaData meta = jdbcConnection.getMetaData(); // if the jdbc driver version is less than 4, it shouldn't have createClob if ( meta.getJDBCMajorVersion() < 4 ) { LOG.disablingContextualLOBCreationSinceOldJdbcVersion( meta.getJDBCMajorVersion() ); return false; } } catch ( SQLException ignore ) { // ignore exception and continue } final Class connectionClass = Connection.class; final Method createClobMethod = connectionClass.getMethod( "createClob", NO_ARG_SIG ); if ( createClobMethod.getDeclaringClass().equals( Connection.class ) ) { // If we get here we are running in a jdk 1.6 (jdbc 4) environment... // Further check to make sure the driver actually implements the LOB creation methods. We // check against createClob() as indicative of all; should we check against all 3 explicitly? try { final Object clob = createClobMethod.invoke( jdbcConnection, NO_ARGS ); try { final Method freeMethod = clob.getClass().getMethod( "free", NO_ARG_SIG ); freeMethod.invoke( clob, NO_ARGS ); } catch ( Throwable ignore ) { LOG.tracef( "Unable to free CLOB created to test createClob() implementation : %s", ignore ); } return true; } catch ( Throwable t ) { LOG.disablingContextualLOBCreationSinceCreateClobFailed( t ); } } } catch ( NoSuchMethodException ignore ) { } return false; }
Build a LobCreator using the given context
Params:
  • lobCreationContext – The LOB creation context
Returns:The LobCreator
/** * Build a LobCreator using the given context * * @param lobCreationContext The LOB creation context * * @return The LobCreator */
public LobCreator buildLobCreator(LobCreationContext lobCreationContext) { return useContextualLobCreation ? new ContextualLobCreator( lobCreationContext ) : NonContextualLobCreator.INSTANCE; } }