HHH-8211 - Checkstyle and FindBugs fix-ups

This commit is contained in:
Steve Ebersole 2013-05-18 11:39:44 -05:00
parent 7a1d2de542
commit 8451c03ea5
28 changed files with 347 additions and 247 deletions

View File

@ -26,7 +26,6 @@ package org.hibernate;
import java.io.Serializable; import java.io.Serializable;
import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
/** /**
* Contract methods shared between {@link Session} and {@link StatelessSession}. * Contract methods shared between {@link Session} and {@link StatelessSession}.

View File

@ -60,14 +60,20 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
@Override @Override
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) { public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
Properties p = new Properties(); final Properties p = new Properties();
if (configurationValues != null) { if (configurationValues != null) {
p.putAll( configurationValues ); p.putAll( configurationValues );
} }
boolean useSecondLevelCache = ConfigurationHelper.getBoolean( AvailableSettings.USE_SECOND_LEVEL_CACHE, final boolean useSecondLevelCache = ConfigurationHelper.getBoolean(
configurationValues, true ); AvailableSettings.USE_SECOND_LEVEL_CACHE,
boolean useQueryCache = ConfigurationHelper.getBoolean( AvailableSettings.USE_QUERY_CACHE, configurationValues ); configurationValues,
true
);
final boolean useQueryCache = ConfigurationHelper.getBoolean(
AvailableSettings.USE_QUERY_CACHE,
configurationValues
);
RegionFactory regionFactory = NoCachingRegionFactory.INSTANCE; RegionFactory regionFactory = NoCachingRegionFactory.INSTANCE;
@ -77,7 +83,7 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
configurationValues, null ); configurationValues, null );
if ( ( useSecondLevelCache || useQueryCache ) && setting != null ) { if ( ( useSecondLevelCache || useQueryCache ) && setting != null ) {
try { try {
Class<? extends RegionFactory> regionFactoryClass = registry.getService( StrategySelector.class ) final Class<? extends RegionFactory> regionFactoryClass = registry.getService( StrategySelector.class )
.selectStrategyImplementor( RegionFactory.class, setting ); .selectStrategyImplementor( RegionFactory.class, setting );
try { try {
regionFactory = regionFactoryClass.getConstructor( Properties.class ).newInstance( p ); regionFactory = regionFactoryClass.getConstructor( Properties.class ).newInstance( p );

View File

@ -283,6 +283,12 @@ public abstract class Dialect implements ConversionContext {
// database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Allows the Dialect to contribute additional types
*
* @param typeContributions Callback to contribute the types
* @param serviceRegistry The service registry
*/
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
// by default, nothing to do // by default, nothing to do
} }
@ -1346,7 +1352,7 @@ public abstract class Dialect implements ConversionContext {
* @param lockOptions the lock options to apply * @param lockOptions the lock options to apply
* @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string. * @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string.
*/ */
@SuppressWarnings( {"unchecked"}) @SuppressWarnings({"unchecked", "UnusedParameters"})
public String getForUpdateString(String aliases, LockOptions lockOptions) { public String getForUpdateString(String aliases, LockOptions lockOptions) {
LockMode lockMode = lockOptions.getLockMode(); LockMode lockMode = lockOptions.getLockMode();
final Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator(); final Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator();
@ -1596,6 +1602,7 @@ public abstract class Dialect implements ConversionContext {
* *
* @throws SQLException Indicates problems registering the param. * @throws SQLException Indicates problems registering the param.
*/ */
@SuppressWarnings("UnusedParameters")
public int registerResultSetOutParameter(CallableStatement statement, String name) throws SQLException { public int registerResultSetOutParameter(CallableStatement statement, String name) throws SQLException {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
getClass().getName() + getClass().getName() +
@ -1628,6 +1635,7 @@ public abstract class Dialect implements ConversionContext {
* *
* @throws SQLException Indicates problems extracting the result set. * @throws SQLException Indicates problems extracting the result set.
*/ */
@SuppressWarnings("UnusedParameters")
public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException { public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
getClass().getName() + " does not support resultsets via stored procedures" getClass().getName() + " does not support resultsets via stored procedures"
@ -1645,6 +1653,7 @@ public abstract class Dialect implements ConversionContext {
* *
* @throws SQLException Indicates problems extracting the result set. * @throws SQLException Indicates problems extracting the result set.
*/ */
@SuppressWarnings("UnusedParameters")
public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException { public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
getClass().getName() + " does not support resultsets via stored procedures" getClass().getName() + " does not support resultsets via stored procedures"

View File

@ -40,7 +40,11 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@SuppressWarnings("deprecation")
public class DialectResolverInitiator implements StandardServiceInitiator<DialectResolver> { public class DialectResolverInitiator implements StandardServiceInitiator<DialectResolver> {
/**
* Singleton access
*/
public static final DialectResolverInitiator INSTANCE = new DialectResolverInitiator(); public static final DialectResolverInitiator INSTANCE = new DialectResolverInitiator();
@Override @Override

View File

@ -48,6 +48,7 @@ import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
import org.hibernate.engine.jdbc.spi.SchemaNameResolver; import org.hibernate.engine.jdbc.spi.SchemaNameResolver;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.engine.jdbc.spi.TypeInfo;
import org.hibernate.exception.internal.SQLExceptionTypeDelegate; import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
import org.hibernate.exception.internal.SQLStateConversionDelegate; import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter; import org.hibernate.exception.internal.StandardSQLExceptionConverter;
@ -122,15 +123,25 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
try { try {
final Connection connection = jdbcConnectionAccess.obtainConnection(); final Connection connection = jdbcConnectionAccess.obtainConnection();
try { try {
DatabaseMetaData meta = connection.getMetaData(); final DatabaseMetaData meta = connection.getMetaData();
if(LOG.isDebugEnabled()) { if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Database ->\n" + " name : %s\n" + " version : %s\n" + " major : %s\n" + " minor : %s", LOG.debugf(
"Database ->\n"
+ " name : %s\n"
+ " version : %s\n"
+ " major : %s\n"
+ " minor : %s",
meta.getDatabaseProductName(), meta.getDatabaseProductName(),
meta.getDatabaseProductVersion(), meta.getDatabaseProductVersion(),
meta.getDatabaseMajorVersion(), meta.getDatabaseMajorVersion(),
meta.getDatabaseMinorVersion() meta.getDatabaseMinorVersion()
); );
LOG.debugf( "Driver ->\n" + " name : %s\n" + " version : %s\n" + " major : %s\n" + " minor : %s", LOG.debugf(
"Driver ->\n"
+ " name : %s\n"
+ " version : %s\n"
+ " major : %s\n"
+ " minor : %s",
meta.getDriverName(), meta.getDriverName(),
meta.getDriverVersion(), meta.getDriverVersion(),
meta.getDriverMajorVersion(), meta.getDriverMajorVersion(),
@ -149,7 +160,7 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
extraKeywordsString = meta.getSQLKeywords(); extraKeywordsString = meta.getSQLKeywords();
sqlStateType = meta.getSQLStateType(); sqlStateType = meta.getSQLStateType();
lobLocatorUpdateCopy = meta.locatorsUpdateCopy(); lobLocatorUpdateCopy = meta.locatorsUpdateCopy();
typeInfoSet.addAll( TypeInfoExtracter.extractTypeInfo( meta ) ); typeInfoSet.addAll( TypeInfo.extractTypeInfo( meta ) );
dialect = dialectFactory.buildDialect( configValues, connection ); dialect = dialectFactory.buildDialect( configValues, connection );

View File

@ -1,105 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc.internal;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashSet;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.ArrayHelper;
/**
* Helper to extract type information from {@link DatabaseMetaData JDBC metadata}
*
* @author Steve Ebersole
*/
public class TypeInfoExtracter {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TypeInfoExtracter.class.getName());
private TypeInfoExtracter() {
}
/**
* Perform the extraction
*
* @param metaData The JDBC metadata
*
* @return The extracted metadata
*/
public static LinkedHashSet<TypeInfo> extractTypeInfo(DatabaseMetaData metaData) {
LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
try {
ResultSet resultSet = metaData.getTypeInfo();
try {
while ( resultSet.next() ) {
typeInfoSet.add(
new TypeInfo(
resultSet.getString( "TYPE_NAME" ),
resultSet.getInt( "DATA_TYPE" ),
interpretCreateParams( resultSet.getString( "CREATE_PARAMS" ) ),
resultSet.getBoolean( "UNSIGNED_ATTRIBUTE" ),
resultSet.getInt( "PRECISION" ),
resultSet.getShort( "MINIMUM_SCALE" ),
resultSet.getShort( "MAXIMUM_SCALE" ),
resultSet.getBoolean( "FIXED_PREC_SCALE" ),
resultSet.getString( "LITERAL_PREFIX" ),
resultSet.getString( "LITERAL_SUFFIX" ),
resultSet.getBoolean( "CASE_SENSITIVE" ),
TypeSearchability.interpret( resultSet.getShort( "SEARCHABLE" ) ),
TypeNullability.interpret( resultSet.getShort( "NULLABLE" ) )
)
);
}
}
catch ( SQLException e ) {
LOG.unableToAccessTypeInfoResultSet( e.toString() );
}
finally {
try {
resultSet.close();
}
catch ( SQLException e ) {
LOG.unableToReleaseTypeInfoResultSet();
}
}
}
catch ( SQLException e ) {
LOG.unableToRetrieveTypeInfoResultSet( e.toString() );
}
return typeInfoSet;
}
private static String[] interpretCreateParams(String value) {
if ( value == null || value.length() == 0 ) {
return ArrayHelper.EMPTY_STRING_ARRAY;
}
return value.split( "," );
}
}

View File

@ -26,6 +26,8 @@ package org.hibernate.engine.jdbc.spi;
import java.sql.Connection; import java.sql.Connection;
/** /**
* A no-op adapter for ConnectionObserver.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ConnectionObserverAdapter implements ConnectionObserver { public class ConnectionObserverAdapter implements ConnectionObserver {

View File

@ -26,8 +26,6 @@ package org.hibernate.engine.jdbc.spi;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import org.hibernate.engine.jdbc.internal.TypeInfo;
/** /**
* Information extracted from {@link java.sql.DatabaseMetaData} regarding what the JDBC driver reports as * Information extracted from {@link java.sql.DatabaseMetaData} regarding what the JDBC driver reports as
* being supported or not. Obviously {@link java.sql.DatabaseMetaData} reports many things, these are a few in * being supported or not. Obviously {@link java.sql.DatabaseMetaData} reports many things, these are a few in
@ -37,10 +35,21 @@ import org.hibernate.engine.jdbc.internal.TypeInfo;
*/ */
@SuppressWarnings( {"UnusedDeclaration"}) @SuppressWarnings( {"UnusedDeclaration"})
public interface ExtractedDatabaseMetaData { public interface ExtractedDatabaseMetaData {
/**
* Which specification do the reported SQLState codes follow?
*/
public enum SQLStateType { public enum SQLStateType {
/**
* The reported codes follow the X/Open spec
*/
XOpen, XOpen,
/**
* The reported codes follow the SQL spec
*/
SQL99, SQL99,
/**
* It is unknown. Might follow another spec completely, or be a mixture.
*/
UNKOWN UNKOWN
} }

View File

@ -56,6 +56,8 @@ public interface JdbcConnectionAccess extends Serializable {
* Does the underlying provider of connections support aggressive releasing of connections (and re-acquisition * Does the underlying provider of connections support aggressive releasing of connections (and re-acquisition
* of those connections later, if need be) in JTA environments? * of those connections later, if need be) in JTA environments?
* *
* @return true/false
*
* @see org.hibernate.engine.jdbc.connections.spi.ConnectionProvider#supportsAggressiveRelease() * @see org.hibernate.engine.jdbc.connections.spi.ConnectionProvider#supportsAggressiveRelease()
* @see org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider#supportsAggressiveRelease() * @see org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider#supportsAggressiveRelease()
*/ */

View File

@ -154,6 +154,7 @@ public interface JdbcCoordinator extends Serializable {
* @throws org.hibernate.TransactionException Indicates the time out period has already been exceeded. * @throws org.hibernate.TransactionException Indicates the time out period has already been exceeded.
*/ */
public int determineRemainingTransactionTimeOutPeriod(); public int determineRemainingTransactionTimeOutPeriod();
/** /**
* Register a JDBC statement. * Register a JDBC statement.
* *
@ -200,8 +201,14 @@ public interface JdbcCoordinator extends Serializable {
*/ */
public void releaseResources(); public void releaseResources();
/**
* Enable connection releases
*/
public void enableReleases(); public void enableReleases();
/**
* Disable connection releases
*/
public void disableReleases(); public void disableReleases();
/** /**
@ -211,5 +218,10 @@ public interface JdbcCoordinator extends Serializable {
*/ */
public void registerLastQuery(Statement statement); public void registerLastQuery(Statement statement);
/**
* Can this coordinator be serialized?
*
* @return {@code true} indicates the coordinator can be serialized.
*/
public boolean isReadyForSerialization(); public boolean isReadyForSerialization();
} }

View File

@ -23,8 +23,6 @@
*/ */
package org.hibernate.engine.jdbc.spi; package org.hibernate.engine.jdbc.spi;
import java.sql.ResultSet;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;
@ -88,7 +86,7 @@ public interface JdbcServices extends Service {
public LobCreator getLobCreator(LobCreationContext lobCreationContext); public LobCreator getLobCreator(LobCreationContext lobCreationContext);
/** /**
* Obtain service for wrapping a {@link ResultSet} in a "column name cache" wrapper. * Obtain service for wrapping a {@link java.sql.ResultSet} in a "column name cache" wrapper.
* @return The ResultSet wrapper. * @return The ResultSet wrapper.
*/ */
public ResultSetWrapper getResultSetWrapper(); public ResultSetWrapper getResultSetWrapper();

View File

@ -79,13 +79,34 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
*/ */
public void manualReconnect(Connection suppliedConnection); public void manualReconnect(Connection suppliedConnection);
/**
* Perform an aggressive release
*/
public void aggressiveRelease(); public void aggressiveRelease();
/**
* Release any held connection.
*
* @throws JDBCException Indicates a problem releasing the connection
*/
public void releaseConnection() throws JDBCException; public void releaseConnection() throws JDBCException;
/**
* Is this logical connection in auto-commit mode?
*
* @return {@code true} if auto-commit
*/
public boolean isAutoCommit(); public boolean isAutoCommit();
/**
* Callback to notify all registered observers of a connection being prepared.
*/
public void notifyObserversStatementPrepared(); public void notifyObserversStatementPrepared();
/**
* Does this logical connection wrap a user/application supplied connection?
*
* @return {@code true} if the underlying connection was user supplied.
*/
public boolean isUserSuppliedConnection(); public boolean isUserSuppliedConnection();
} }

View File

@ -35,74 +35,83 @@ import java.sql.Statement;
* TODO: This could eventually utilize the new Return interface. It would be * TODO: This could eventually utilize the new Return interface. It would be
* great to have a common API shared. * great to have a common API shared.
* *
* Generally the methods here dealing with CallableStatement are extremely limited, relying on the legacy
*
*
* @author Brett Meyer * @author Brett Meyer
* @author Steve Ebersole
*/ */
public interface ResultSetReturn { public interface ResultSetReturn {
/** /**
* Extract the ResultSet from the statement. If user passes {@link CallableStatement} * Extract the ResultSet from the PreparedStatement.
* reference, method calls {@link #extract(CallableStatement)} internally. * <p/>
* If user passes {@link CallableStatement} reference, this method calls {@link #extract(CallableStatement)}
* internally. Otherwise, generally speaking, {@link java.sql.PreparedStatement#executeQuery()} is called
* *
* @param statement * @param statement The PreparedStatement from which to extract the ResultSet
* *
* @return the ResultSet * @return The extracted ResultSet
*/ */
public ResultSet extract( PreparedStatement statement ); public ResultSet extract(PreparedStatement statement);
/** /**
* Extract the ResultSet from the statement. * Extract the ResultSet from the CallableStatement. Note that this is the limited legacy form which delegates to
* {@link org.hibernate.dialect.Dialect#getResultSet}. Better option is to integrate
* {@link org.hibernate.procedure.ProcedureCall}-like hooks
* *
* @param statement * @param callableStatement The CallableStatement from which to extract the ResultSet
* *
* @return the ResultSet * @return The extracted ResultSet
*/ */
public ResultSet extract( CallableStatement statement ); public ResultSet extract(CallableStatement callableStatement);
/** /**
* Extract the ResultSet from the statement. * Performs the given SQL statement, expecting a ResultSet in return
* *
* @param statement * @param statement The JDBC Statement object to use
* @param sql * @param sql The SQL to execute
* *
* @return the ResultSet * @return The resulting ResultSet
*/ */
public ResultSet extract( Statement statement, String sql ); public ResultSet extract(Statement statement, String sql);
/** /**
* Execute the Statement query and, if results in a ResultSet, extract it. * Execute the PreparedStatement return its first ResultSet, if any. If there is no ResultSet, returns {@code null}
* *
* @param statement * @param statement The PreparedStatement to execute
* *
* @return the ResultSet * @return The extracted ResultSet, or {@code null}
*/ */
public ResultSet execute( PreparedStatement statement ); public ResultSet execute(PreparedStatement statement);
/** /**
* Execute the Statement query and, if results in a ResultSet, extract it. * Performs the given SQL statement, returning its first ResultSet, if any. If there is no ResultSet,
* returns {@code null}
* *
* @param statement * @param statement The JDBC Statement object to use
* @param sql * @param sql The SQL to execute
* *
* @return the ResultSet * @return The extracted ResultSet, or {@code null}
*/ */
public ResultSet execute( Statement statement, String sql ); public ResultSet execute(Statement statement, String sql);
/** /**
* Execute the Statement queryUpdate. * Execute the PreparedStatement, returning its "affected row count".
* *
* @param statement * @param statement The PreparedStatement to execute
* *
* @return int * @return The {@link java.sql.PreparedStatement#executeUpdate()} result
*/ */
public int executeUpdate( PreparedStatement statement ); public int executeUpdate(PreparedStatement statement);
/** /**
* Execute the Statement query and, if results in a ResultSet, extract it. * Execute the given SQL statement returning its "affected row count".
* *
* @param statement * @param statement The JDBC Statement object to use
* @param sql * @param sql The SQL to execute
* *
* @return the ResultSet * @return The {@link java.sql.PreparedStatement#executeUpdate(String)} result
*/ */
public int executeUpdate( Statement statement, String sql ); public int executeUpdate(Statement statement, String sql);
} }

View File

@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc.spi; package org.hibernate.engine.jdbc.spi;
import java.sql.Connection; import java.sql.Connection;
/** /**

View File

@ -95,6 +95,12 @@ public class SqlStatementLogger {
logStatement( statement, FormatStyle.BASIC.getFormatter() ); logStatement( statement, FormatStyle.BASIC.getFormatter() );
} }
/**
* Log a SQL statement string using the specified formatter
*
* @param statement The SQL statement.
* @param formatter The formatter to use.
*/
public void logStatement(String statement, Formatter formatter) { public void logStatement(String statement, Formatter formatter) {
if ( format ) { if ( format ) {
if ( logToStdout || LOG.isDebugEnabled() ) { if ( logToStdout || LOG.isDebugEnabled() ) {

View File

@ -38,8 +38,6 @@ public interface StatementPreparer {
/** /**
* Create a statement. * Create a statement.
* *
* @param sql The SQL the statement to be created
*
* @return the statement * @return the statement
*/ */
public Statement createStatement(); public Statement createStatement();
@ -64,14 +62,15 @@ public interface StatementPreparer {
public PreparedStatement prepareStatement(String sql, boolean isCallable); public PreparedStatement prepareStatement(String sql, boolean isCallable);
/** /**
* Get a prepared statement to use for inserting using JDBC3 * Prepare an INSERT statement, specifying how auto-generated (by the database) keys should be handled. Really this
* {@link java.sql.PreparedStatement#getGeneratedKeys getGeneratedKeys} processing. * is a boolean, but JDBC opted to define it instead using 2 int constants:<ul>
*
* @param sql - the SQL for the statement to be prepared
* @param autoGeneratedKeys - a flag indicating whether auto-generated keys should be returned; one of<ul>
* <li>{@link PreparedStatement#RETURN_GENERATED_KEYS}</li> * <li>{@link PreparedStatement#RETURN_GENERATED_KEYS}</li>
* <li>{@link PreparedStatement#NO_GENERATED_KEYS}</li> * <li>{@link PreparedStatement#NO_GENERATED_KEYS}</li>
* </li> * </ul>
* Generated keys are accessed afterwards via {@link java.sql.PreparedStatement#getGeneratedKeys}
*
* @param sql The INSERT SQL
* @param autoGeneratedKeys The autoGeneratedKeys flag
* *
* @return the prepared statement * @return the prepared statement
* *
@ -79,10 +78,9 @@ public interface StatementPreparer {
*/ */
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys); public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys);
/** /**
* Get a prepared statement to use for inserting using JDBC3 * Prepare an INSERT statement, specifying columns which are auto-generated values to be returned.
* {@link java.sql.PreparedStatement#getGeneratedKeys getGeneratedKeys} processing. * Generated keys are accessed afterwards via {@link java.sql.PreparedStatement#getGeneratedKeys}
* *
* @param sql - the SQL for the statement to be prepared * @param sql - the SQL for the statement to be prepared
* @param columnNames The name of the columns to be returned in the generated keys result set. * @param columnNames The name of the columns to be returned in the generated keys result set.

View File

@ -21,15 +21,30 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc.internal; package org.hibernate.engine.jdbc.spi;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashSet;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.ArrayHelper;
/** /**
* Models type info extracted from {@link java.sql.DatabaseMetaData#getTypeInfo()} * Models type info extracted from {@link java.sql.DatabaseMetaData#getTypeInfo()}
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@SuppressWarnings("UnusedDeclaration")
public class TypeInfo { public class TypeInfo {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
TypeInfo.class.getName()
);
private final String typeName; private final String typeName;
private final int jdbcTypeCode; private final int jdbcTypeCode;
private final String[] createParams; private final String[] createParams;
@ -44,7 +59,7 @@ public class TypeInfo {
private final TypeSearchability searchability; private final TypeSearchability searchability;
private final TypeNullability nullability; private final TypeNullability nullability;
public TypeInfo( private TypeInfo(
String typeName, String typeName,
int jdbcTypeCode, int jdbcTypeCode,
String[] createParams, String[] createParams,
@ -73,6 +88,64 @@ public class TypeInfo {
this.nullability = nullability; this.nullability = nullability;
} }
/**
* Extract the type information from the JDBC driver's DatabaseMetaData
*
* @param metaData The JDBC metadata
*
* @return The extracted type info
*/
public static LinkedHashSet<TypeInfo> extractTypeInfo(DatabaseMetaData metaData) {
final LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
try {
final ResultSet resultSet = metaData.getTypeInfo();
try {
while ( resultSet.next() ) {
typeInfoSet.add(
new TypeInfo(
resultSet.getString( "TYPE_NAME" ),
resultSet.getInt( "DATA_TYPE" ),
interpretCreateParams( resultSet.getString( "CREATE_PARAMS" ) ),
resultSet.getBoolean( "UNSIGNED_ATTRIBUTE" ),
resultSet.getInt( "PRECISION" ),
resultSet.getShort( "MINIMUM_SCALE" ),
resultSet.getShort( "MAXIMUM_SCALE" ),
resultSet.getBoolean( "FIXED_PREC_SCALE" ),
resultSet.getString( "LITERAL_PREFIX" ),
resultSet.getString( "LITERAL_SUFFIX" ),
resultSet.getBoolean( "CASE_SENSITIVE" ),
TypeSearchability.interpret( resultSet.getShort( "SEARCHABLE" ) ),
TypeNullability.interpret( resultSet.getShort( "NULLABLE" ) )
)
);
}
}
catch ( SQLException e ) {
LOG.unableToAccessTypeInfoResultSet( e.toString() );
}
finally {
try {
resultSet.close();
}
catch ( SQLException e ) {
LOG.unableToReleaseTypeInfoResultSet();
}
}
}
catch ( SQLException e ) {
LOG.unableToRetrieveTypeInfoResultSet( e.toString() );
}
return typeInfoSet;
}
private static String[] interpretCreateParams(String value) {
if ( value == null || value.length() == 0 ) {
return ArrayHelper.EMPTY_STRING_ARRAY;
}
return value.split( "," );
}
public String getTypeName() { public String getTypeName() {
return typeName; return typeName;
} }

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc.internal; package org.hibernate.engine.jdbc.spi;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc.internal; package org.hibernate.engine.jdbc.spi;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;

View File

@ -30,7 +30,13 @@ import org.hibernate.HibernateException;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JndiException extends HibernateException { public class JndiException extends HibernateException {
public JndiException(String string, Throwable root) { /**
super( string, root ); * Constructs a JndiException
*
* @param message Message explaining the exception condition
* @param cause The underlying cause
*/
public JndiException(String message, Throwable cause) {
super( message, cause );
} }
} }

View File

@ -31,7 +31,13 @@ import org.hibernate.HibernateException;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JndiNameException extends HibernateException { public class JndiNameException extends HibernateException {
public JndiNameException(String string, Throwable root) { /**
super( string, root ); * Constructs a JndiNameException
*
* @param message Message explaining the exception condition
* @param cause The underlying cause.
*/
public JndiNameException(String message, Throwable cause) {
super( message, cause );
} }
} }

View File

@ -25,6 +25,8 @@ package org.hibernate.engine.jndi.internal;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.InvalidNameException; import javax.naming.InvalidNameException;
@ -36,8 +38,8 @@ import javax.naming.event.NamespaceChangeListener;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.jndi.JndiHelper;
import org.hibernate.engine.jndi.JndiException; import org.hibernate.engine.jndi.JndiException;
import org.hibernate.engine.jndi.JndiNameException; import org.hibernate.engine.jndi.JndiNameException;
import org.hibernate.engine.jndi.spi.JndiService; import org.hibernate.engine.jndi.spi.JndiService;
@ -48,19 +50,66 @@ import org.hibernate.engine.jndi.spi.JndiService;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JndiServiceImpl implements JndiService { public class JndiServiceImpl implements JndiService {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, JndiServiceImpl.class.getName()); CoreMessageLogger.class,
JndiServiceImpl.class.getName()
);
private final Hashtable initialContextSettings; private final Hashtable initialContextSettings;
/**
* Constructs a JndiServiceImpl
*
* @param configurationValues Map of configuration settings, some of which apply to JNDI support.
*/
public JndiServiceImpl(Map configurationValues) { public JndiServiceImpl(Map configurationValues) {
this.initialContextSettings = JndiHelper.extractJndiProperties( configurationValues ); this.initialContextSettings = extractJndiProperties( configurationValues );
}
/**
* Given a hodgepodge of properties, extract out the ones relevant for JNDI interaction.
*
* @param configurationValues The map of config values
*
* @return The extracted JNDI specific properties.
*/
@SuppressWarnings({ "unchecked" })
public static Properties extractJndiProperties(Map configurationValues) {
final Properties jndiProperties = new Properties();
for ( Map.Entry entry : (Set<Map.Entry>) configurationValues.entrySet() ) {
if ( !String.class.isInstance( entry.getKey() ) ) {
continue;
}
final String propertyName = (String) entry.getKey();
final Object propertyValue = entry.getValue();
if ( propertyName.startsWith( Environment.JNDI_PREFIX ) ) {
// write the IntialContextFactory class and provider url to the result only if they are
// non-null; this allows the environmental defaults (if any) to remain in effect
if ( Environment.JNDI_CLASS.equals( propertyName ) ) {
if ( propertyValue != null ) {
jndiProperties.put( Context.INITIAL_CONTEXT_FACTORY, propertyValue );
}
}
else if ( Environment.JNDI_URL.equals( propertyName ) ) {
if ( propertyValue != null ) {
jndiProperties.put( Context.PROVIDER_URL, propertyValue );
}
}
else {
final String passThruPropertyname = propertyName.substring( Environment.JNDI_PREFIX.length() + 1 );
jndiProperties.put( passThruPropertyname, propertyValue );
}
}
}
return jndiProperties;
} }
@Override @Override
public Object locate(String jndiName) { public Object locate(String jndiName) {
InitialContext initialContext = buildInitialContext(); final InitialContext initialContext = buildInitialContext();
Name name = parseName( jndiName, initialContext ); final Name name = parseName( jndiName, initialContext );
try { try {
return initialContext.lookup( name ); return initialContext.lookup( name );
} }
@ -104,8 +153,8 @@ public class JndiServiceImpl implements JndiService {
@Override @Override
public void bind(String jndiName, Object value) { public void bind(String jndiName, Object value) {
InitialContext initialContext = buildInitialContext(); final InitialContext initialContext = buildInitialContext();
Name name = parseName( jndiName, initialContext ); final Name name = parseName( jndiName, initialContext );
try { try {
bind( name, value, initialContext ); bind( name, value, initialContext );
} }
@ -172,8 +221,8 @@ public class JndiServiceImpl implements JndiService {
@Override @Override
public void unbind(String jndiName) { public void unbind(String jndiName) {
InitialContext initialContext = buildInitialContext(); final InitialContext initialContext = buildInitialContext();
Name name = parseName( jndiName, initialContext ); final Name name = parseName( jndiName, initialContext );
try { try {
initialContext.unbind( name ); initialContext.unbind( name );
} }
@ -187,8 +236,8 @@ public class JndiServiceImpl implements JndiService {
@Override @Override
public void addListener(String jndiName, NamespaceChangeListener listener) { public void addListener(String jndiName, NamespaceChangeListener listener) {
InitialContext initialContext = buildInitialContext(); final InitialContext initialContext = buildInitialContext();
Name name = parseName( jndiName, initialContext ); final Name name = parseName( jndiName, initialContext );
try { try {
( (EventContext) initialContext ).addNamingListener( name, EventContext.OBJECT_SCOPE, listener ); ( (EventContext) initialContext ).addNamingListener( name, EventContext.OBJECT_SCOPE, listener );
} }

View File

@ -35,6 +35,9 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JndiServiceInitiator implements StandardServiceInitiator<JndiService> { public class JndiServiceInitiator implements StandardServiceInitiator<JndiService> {
/**
* Singleton access
*/
public static final JndiServiceInitiator INSTANCE = new JndiServiceInitiator(); public static final JndiServiceInitiator INSTANCE = new JndiServiceInitiator();
@Override @Override

View File

@ -0,0 +1,4 @@
/**
* Internal contracts defining the JNDI support within Hibernate
*/
package org.hibernate.engine.jndi.internal;

View File

@ -0,0 +1,4 @@
/**
* Support for JNDI within Hibernate
*/
package org.hibernate.engine.jndi;

View File

@ -0,0 +1,4 @@
/**
* The SPI contracts for Hibernate JNDI support
*/
package org.hibernate.engine.jndi.spi;

View File

@ -23,17 +23,16 @@
*/ */
package org.hibernate.internal.util.jndi; package org.hibernate.internal.util.jndi;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.Name; import javax.naming.Name;
import javax.naming.NameNotFoundException; import javax.naming.NameNotFoundException;
import javax.naming.NamingException; import javax.naming.NamingException;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import org.hibernate.cfg.Environment; import org.hibernate.engine.jndi.internal.JndiServiceImpl;
/** /**
* Helper for dealing with JNDI. * Helper for dealing with JNDI.
@ -54,42 +53,12 @@ public final class JndiHelper {
*/ */
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
public static Properties extractJndiProperties(Map configurationValues) { public static Properties extractJndiProperties(Map configurationValues) {
final Properties jndiProperties = new Properties(); return JndiServiceImpl.extractJndiProperties( configurationValues );
for ( Map.Entry entry : (Set<Map.Entry>) configurationValues.entrySet() ) {
if ( !String.class.isInstance( entry.getKey() ) ) {
continue;
}
final String propertyName = (String) entry.getKey();
final Object propertyValue = entry.getValue();
if ( propertyName.startsWith( Environment.JNDI_PREFIX ) ) {
// write the IntialContextFactory class and provider url to the result only if they are
// non-null; this allows the environmental defaults (if any) to remain in effect
if ( Environment.JNDI_CLASS.equals( propertyName ) ) {
if ( propertyValue != null ) {
jndiProperties.put( Context.INITIAL_CONTEXT_FACTORY, propertyValue );
}
}
else if ( Environment.JNDI_URL.equals( propertyName ) ) {
if ( propertyValue != null ) {
jndiProperties.put( Context.PROVIDER_URL, propertyValue );
}
}
else {
final String passThruPropertyname = propertyName.substring( Environment.JNDI_PREFIX.length() + 1 );
jndiProperties.put( passThruPropertyname, propertyValue );
}
}
}
return jndiProperties;
} }
public static InitialContext getInitialContext(Properties props) throws NamingException { public static InitialContext getInitialContext(Properties props) throws NamingException {
Hashtable hash = extractJndiProperties(props); final Hashtable hash = extractJndiProperties( props );
return hash.size()==0 ? return hash.size() == 0 ? new InitialContext() : new InitialContext( hash );
new InitialContext() :
new InitialContext(hash);
} }
/** /**
@ -106,26 +75,26 @@ public final class JndiHelper {
ctx.rebind(name, val); ctx.rebind(name, val);
} }
catch (Exception e) { catch (Exception e) {
Name n = ctx.getNameParser("").parse(name); Name n = ctx.getNameParser( "" ).parse( name );
while ( n.size() > 1 ) { while ( n.size() > 1 ) {
String ctxName = n.get(0); final String ctxName = n.get( 0 );
Context subctx=null; Context subctx = null;
try { try {
subctx = (Context) ctx.lookup(ctxName); subctx = (Context) ctx.lookup( ctxName );
} }
catch (NameNotFoundException ignore) { catch (NameNotFoundException ignore) {
} }
if (subctx!=null) { if ( subctx != null ) {
ctx = subctx; ctx = subctx;
} }
else { else {
ctx = ctx.createSubcontext(ctxName); ctx = ctx.createSubcontext( ctxName );
} }
n = n.getSuffix(1); n = n.getSuffix( 1 );
} }
ctx.rebind(n, val); ctx.rebind( n, val );
} }
} }
} }

View File

@ -31,7 +31,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.internal.ResultSetWrapperImpl; import org.hibernate.engine.jdbc.internal.ResultSetWrapperImpl;
import org.hibernate.engine.jdbc.internal.TypeInfo; import org.hibernate.engine.jdbc.spi.TypeInfo;
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData; import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.ResultSetWrapper; import org.hibernate.engine.jdbc.spi.ResultSetWrapper;