HHH-8159 - Apply fixups indicated by analysis tools

This commit is contained in:
Steve Ebersole 2013-04-29 18:52:08 -05:00
parent 0edd7b75b8
commit 3b8320da7e
49 changed files with 473 additions and 209 deletions

View File

@ -59,7 +59,9 @@ public class TemplateRenderer {
final StringBuilder chunk = new StringBuilder( 10 );
final StringBuilder index = new StringBuilder( 2 );
for ( int i = 0; i < template.length(); ++i ) {
int i = 0;
final int len = template.length();
while ( i < len ) {
char c = template.charAt( i );
if ( c == '?' ) {
chunkList.add( chunk.toString() );
@ -82,6 +84,7 @@ public class TemplateRenderer {
else {
chunk.append( c );
}
i++;
}
if ( chunk.length() > 0 ) {
@ -90,7 +93,7 @@ public class TemplateRenderer {
chunks = chunkList.toArray( new String[chunkList.size()] );
paramIndexes = new int[paramList.size()];
for ( int i = 0; i < paramIndexes.length; ++i ) {
for ( i = 0; i < paramIndexes.length; ++i ) {
paramIndexes[i] = paramList.get( i );
}
}

View File

@ -56,6 +56,15 @@ public enum OptimisticLockStyle {
return oldCode;
}
/**
* Given an old code (one of the int constants from Cascade), interpret it as one of the new enums.
*
* @param oldCode The old int constant code
*
* @return The interpreted enum value
*
* @throws IllegalArgumentException If the code did not match any legacy constant.
*/
public static OptimisticLockStyle interpretOldCode(int oldCode) {
switch ( oldCode ) {
case -1: {

View File

@ -33,10 +33,47 @@ import org.hibernate.service.Service;
* @author Steve Ebersole
*/
public interface ConfigurationService extends Service {
/**
* Access to the complete map of config settings. The returned map is immutable
*
* @return The immutable map of config settings.
*/
public Map getSettings();
/**
* Get the named setting, using the specified converter.
*
* @param name The name of the setting to get.
* @param converter The converter to apply
* @param <T> The Java type of the conversion
*
* @return The converted (typed) setting. May return {@code null} (see {@link #getSetting(String, Class, Object)})
*/
public <T> T getSetting(String name, Converter<T> converter);
/**
* Get the named setting, using the specified converter and default value.
*
* @param name The name of the setting to get.
* @param converter The converter to apply
* @param defaultValue If no setting with that name is found, return this default value as the result.
* @param <T> The Java type of the conversion
*
* @return The converted (typed) setting. Will be the defaultValue if no such setting was defined.
*/
public <T> T getSetting(String name, Converter<T> converter, T defaultValue);
/**
* Get the named setting. Differs from the form taking a Converter in that here we expect to have a simple
* cast rather than any involved conversion.
*
* @param name The name of the setting to get.
* @param expected The expected Java type.
* @param defaultValue If no setting with that name is found, return this default value as the result.
* @param <T> The Java type of the conversion
*
* @return The converted (typed) setting. Will be the defaultValue if no such setting was defined.
*/
public <T> T getSetting(String name, Class<T> expected, T defaultValue);
/**
@ -44,10 +81,28 @@ public interface ConfigurationService extends Service {
*
* @param expected The type of instance expected to return.
* @param candidate The candidate object to be casted.
* @param <T> The java type of the expected return
*
* @return The instance of expected type or null if this cast fail.
*
* @deprecated No idea why this is exposed here...
*/
@Deprecated
public <T> T cast(Class<T> expected, Object candidate);
/**
* Simple conversion contract for converting an untyped object to a specified type.
*
* @param <T> The Java type of the converted value
*/
public static interface Converter<T> {
/**
* Convert an untyped Object reference to the Converter's type.
*
* @param value The untyped value
*
* @return The converted (typed) value.
*/
public T convert(Object value);
}
}

View File

@ -258,7 +258,7 @@ public final class Cascade {
final Object[] children = componentType.getPropertyValues( child, eventSource );
final Type[] types = componentType.getSubtypes();
for ( int i=0; i<types.length; i++ ) {
final CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
final CascadeStyle componentPropertyStyle = componentType.getCascadeStyle( i );
final String subPropertyName = componentType.getPropertyNames()[i];
if ( componentPropertyStyle.doCascade( action ) ) {
cascadeProperty(

View File

@ -343,6 +343,8 @@ public class EntityEntryContext {
* @param ois The stream to read ourselves from
* @param rtn The persistence context we belong to
*
* @return The deserialized EntityEntryContext
*
* @throws IOException Indicates an IO exception accessing the given stream
* @throws ClassNotFoundException Problem reading stream data
*/

View File

@ -89,6 +89,8 @@ public final class ForeignKeys {
*
* @param value An entity attribute value
* @param type An entity attribute type
*
* @return {@code null} if the argument is an unsaved entity; otherwise return the argument.
*/
private Object nullifyTransientReferences(final Object value, final Type type)
throws HibernateException {

View File

@ -33,12 +33,21 @@ import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.AssociationType;
/**
* Helper for dealing with joins.
*
* @author Gavin King
*/
public final class JoinHelper {
/**
* Get the aliased columns of the owning entity which are to
* be used in the join
* Get the qualified (prefixed by alias) names of the columns of the owning entity which are to be used in the join
*
* @param type The association type for the association that represents the join
* @param alias The left-hand side table alias
* @param property The index of the property that represents the association/join
* @param lhsPersister The persister for the left-hand side of the association/join
* @param mapping The mapping (typically the SessionFactory).
*
* @return The qualified column names.
*/
public static String[] getAliasedLHSColumnNames(
AssociationType type,
@ -50,8 +59,14 @@ public final class JoinHelper {
}
/**
* Get the columns of the owning entity which are to
* be used in the join
* Get the unqualified names of the columns of the owning entity which are to be used in the join.
*
* @param type The association type for the association that represents the join
* @param property The name of the property that represents the association/join
* @param lhsPersister The persister for the left-hand side of the association/join
* @param mapping The mapping (typically the SessionFactory).
*
* @return The unqualified column names.
*/
public static String[] getLHSColumnNames(
AssociationType type,
@ -62,8 +77,19 @@ public final class JoinHelper {
}
/**
* Get the aliased columns of the owning entity which are to
* be used in the join
*
*/
/**
* Get the qualified (prefixed by alias) names of the columns of the owning entity which are to be used in the join
*
* @param associationType The association type for the association that represents the join
* @param columnQualifier The left-hand side table alias
* @param propertyIndex The index of the property that represents the association/join
* @param begin The index for any nested (composites) attributes
* @param lhsPersister The persister for the left-hand side of the association/join
* @param mapping The mapping (typically the SessionFactory).
*
* @return The qualified column names.
*/
public static String[] getAliasedLHSColumnNames(
AssociationType associationType,
@ -76,7 +102,7 @@ public final class JoinHelper {
return StringHelper.qualify( columnQualifier, lhsPersister.getIdentifierColumnNames() );
}
else {
String propertyName = associationType.getLHSPropertyName();
final String propertyName = associationType.getLHSPropertyName();
if ( propertyName == null ) {
return ArrayHelper.slice(
toColumns( lhsPersister, columnQualifier, propertyIndex ),

View File

@ -404,7 +404,7 @@ public class NaturalIdXrefDelegate {
}
final CachedNaturalId other = (CachedNaturalId) obj;
return persister.equals( other.persister ) && isSame(other.values );
return persister.equals( other.persister ) && isSame( other.values );
}
private boolean isSame(Object[] otherValues) {

View File

@ -156,7 +156,7 @@ public final class Nullability {
final CompositeType componentType = (CompositeType) collectionElementType;
final Iterator itr = CascadingActions.getLoadedElementsIterator( session, collectionType, value );
while ( itr.hasNext() ) {
Object compValue = itr.next();
final Object compValue = itr.next();
if ( compValue != null ) {
return checkComponentNullability( compValue, componentType );
}

View File

@ -146,7 +146,7 @@ public class ParameterBinder {
final Map.Entry e = (Map.Entry) iter.next();
final String name = (String) e.getKey();
final TypedValue typedVal = (TypedValue) e.getValue();
int[] locations = source.getNamedParameterLocations( name );
final int[] locations = source.getNamedParameterLocations( name );
for ( int location : locations ) {
if ( debugEnabled ) {
LOG.debugf(

View File

@ -394,7 +394,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
@Override
public boolean containsEntity(EntityKey key) {
return entitiesByKey.containsKey(key);
return entitiesByKey.containsKey( key );
}
@Override

View File

@ -94,7 +94,7 @@ public final class TwoPhaseLoad {
final Object object,
final LockMode lockMode,
final boolean lazyPropertiesAreUnFetched,
final SessionImplementor session) throws HibernateException {
final SessionImplementor session) {
final Object version = Versioning.getVersion( values, persister );
session.getPersistenceContext().addEntry(
object,

View File

@ -82,7 +82,7 @@ public class UnsavedValueFactory {
if ( unsavedValue == null ) {
if ( identifierGetter != null && constructor != null ) {
// use the id value of a newly instantiated instance as the unsaved-value
final Serializable defaultValue = (Serializable) identifierGetter.get( instantiate(constructor) );
final Serializable defaultValue = (Serializable) identifierGetter.get( instantiate( constructor ) );
return new IdentifierValue( defaultValue );
}
else if ( identifierGetter != null && (identifierType instanceof PrimitiveType) ) {

View File

@ -47,7 +47,7 @@ public class BlobProxy implements InvocationHandler {
private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, BlobImplementer.class };
private BinaryStream binaryStream;
private boolean needsReset = false;
private boolean needsReset;
/**
* Constructor used to build {@link Blob} from byte array.
@ -75,7 +75,7 @@ public class BlobProxy implements InvocationHandler {
}
private InputStream getStream() throws SQLException {
InputStream stream = binaryStream.getInputStream();
final InputStream stream = binaryStream.getInputStream();
try {
if ( needsReset ) {
stream.reset();
@ -92,8 +92,7 @@ public class BlobProxy implements InvocationHandler {
* {@inheritDoc}
*
* @throws UnsupportedOperationException if any methods other than
* {@link Blob#length}, {@link Blob#getUnderlyingStream},
* {@link Blob#getBinaryStream}, {@link Blob#getBytes}, {@link Blob#free},
* {@link Blob#length}, {@link Blob#getBinaryStream}, {@link Blob#getBytes}, {@link Blob#free},
* or toString/equals/hashCode are invoked.
*/
@Override
@ -120,7 +119,7 @@ public class BlobProxy implements InvocationHandler {
if ( start > getLength() ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + getLength() + "]" );
}
int length = (Integer) args[1];
final int length = (Integer) args[1];
if ( length < 0 ) {
// java docs specifically say for getBinaryStream(long,int) that the start+length must not exceed the
// total length, however that is at odds with the getBytes(long,int) behavior.
@ -131,11 +130,11 @@ public class BlobProxy implements InvocationHandler {
}
if ( "getBytes".equals( methodName ) ) {
if ( argCount == 2 ) {
long start = (Long) args[0];
final long start = (Long) args[0];
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
int length = (Integer) args[1];
final int length = (Integer) args[1];
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
@ -167,11 +166,7 @@ public class BlobProxy implements InvocationHandler {
* @return The generated proxy.
*/
public static Blob generateProxy(byte[] bytes) {
return ( Blob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new BlobProxy( bytes )
);
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( bytes ) );
}
/**
@ -183,11 +178,7 @@ public class BlobProxy implements InvocationHandler {
* @return The generated proxy.
*/
public static Blob generateProxy(InputStream stream, long length) {
return ( Blob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new BlobProxy( stream, length )
);
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( stream, length ) );
}
/**

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.engine.jdbc;
import java.io.InputStream;
import java.io.Reader;
/**

View File

@ -26,7 +26,6 @@ package org.hibernate.engine.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@ -49,7 +48,7 @@ public class ClobProxy implements InvocationHandler {
private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, ClobImplementer.class };
private final CharacterStream characterStream;
private boolean needsReset = false;
private boolean needsReset;
/**
* Constructor used to build {@link Clob} from string data.
@ -89,8 +88,8 @@ public class ClobProxy implements InvocationHandler {
protected String getSubString(long start, int length) {
final String string = characterStream.asString();
// semi-naive implementation
int endIndex = Math.min( ((int)start)+length, string.length() );
return string.substring( (int)start, endIndex );
final int endIndex = Math.min( ( (int) start ) + length, string.length() );
return string.substring( (int) start, endIndex );
}
/**
@ -119,14 +118,14 @@ public class ClobProxy implements InvocationHandler {
return getCharacterStream();
}
else if ( argCount == 2 ) {
long start = (Long) args[0];
final long start = (Long) args[0];
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > getLength() ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + getLength() + "]" );
}
int length = (Integer) args[1];
final int length = (Integer) args[1];
if ( length < 0 ) {
// java docs specifically say for getCharacterStream(long,int) that the start+length must not exceed the
// total length, however that is at odds with the getSubString(long,int) behavior.
@ -136,14 +135,14 @@ public class ClobProxy implements InvocationHandler {
}
}
if ( "getSubString".equals( methodName ) && argCount == 2 ) {
long start = (Long) args[0];
final long start = (Long) args[0];
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > getLength() ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + getLength() + "]" );
}
int length = (Integer) args[1];
final int length = (Integer) args[1];
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
@ -186,11 +185,7 @@ public class ClobProxy implements InvocationHandler {
* @return The generated proxy.
*/
public static Clob generateProxy(String string) {
return ( Clob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new ClobProxy( string )
);
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( string ) );
}
/**
@ -202,11 +197,7 @@ public class ClobProxy implements InvocationHandler {
* @return The generated proxy.
*/
public static Clob generateProxy(Reader reader, long length) {
return ( Clob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new ClobProxy( reader, length )
);
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( reader, length ) );
}
/**

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008, 2013, 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 Middleware LLC.
* 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
@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
@ -33,24 +34,42 @@ import java.util.concurrent.ConcurrentHashMap;
* @author Steve Ebersole
*/
public class ColumnNameCache {
public static final float LOAD_FACTOR = .75f;
private static final float LOAD_FACTOR = .75f;
private final Map<String, Integer> columnNameToIndexCache;
/**
* Constructs a ColumnNameCache
*
* @param columnCount The number of columns to be cached.
*/
public ColumnNameCache(int columnCount) {
// should *not* need to grow beyond the size of the total number of columns in the rs
this.columnNameToIndexCache = new ConcurrentHashMap<String, Integer>( columnCount + (int)( columnCount * LOAD_FACTOR ) + 1, LOAD_FACTOR );
this.columnNameToIndexCache = new ConcurrentHashMap<String, Integer>(
columnCount + (int)( columnCount * LOAD_FACTOR ) + 1,
LOAD_FACTOR
);
}
/**
* Resolve the column name/alias to its index
*
* @param columnName The name/alias of the column
* @param rs The ResultSet
*
* @return The index
*
* @throws SQLException INdicates a problems accessing the underlying JDBC ResultSet
*/
public int getIndexForColumnName(String columnName, ResultSet rs) throws SQLException {
Integer cached = columnNameToIndexCache.get( columnName );
final Integer cached = columnNameToIndexCache.get( columnName );
if ( cached != null ) {
return cached;
}
else {
int index = rs.findColumn( columnName );
final int index = rs.findColumn( columnName );
columnNameToIndexCache.put( columnName, index);
return index;
}
}
}
}

View File

@ -22,18 +22,15 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.NClob;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.JDBCException;
/**
@ -46,6 +43,11 @@ import org.hibernate.JDBCException;
public class ContextualLobCreator extends AbstractLobCreator implements LobCreator {
private LobCreationContext lobCreationContext;
/**
* Constructs a ContextualLobCreator
*
* @param lobCreationContext The context for performing LOB creation
*/
public ContextualLobCreator(LobCreationContext lobCreationContext) {
this.lobCreationContext = lobCreationContext;
}
@ -62,7 +64,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
@Override
public Blob createBlob(byte[] bytes) {
try {
Blob blob = createBlob();
final Blob blob = createBlob();
blob.setBytes( 1, bytes );
return blob;
}
@ -90,7 +92,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
@Override
public Clob createClob(String string) {
try {
Clob clob = createClob();
final Clob clob = createClob();
clob.setString( 1, string );
return clob;
}
@ -118,7 +120,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
@Override
public NClob createNClob(String string) {
try {
NClob nclob = createNClob();
final NClob nclob = createNClob();
nclob.setString( 1, string );
return nclob;
}
@ -134,19 +136,31 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
return NonContextualLobCreator.INSTANCE.createNClob( reader, length );
}
/**
* Callback for performing contextual BLOB creation
*/
public static final LobCreationContext.Callback<Blob> CREATE_BLOB_CALLBACK = new LobCreationContext.Callback<Blob>() {
@Override
public Blob executeOnConnection(Connection connection) throws SQLException {
return connection.createBlob();
}
};
/**
* Callback for performing contextual CLOB creation
*/
public static final LobCreationContext.Callback<Clob> CREATE_CLOB_CALLBACK = new LobCreationContext.Callback<Clob>() {
@Override
public Clob executeOnConnection(Connection connection) throws SQLException {
return connection.createClob();
}
};
/**
* Callback for performing contextual NCLOB creation
*/
public static final LobCreationContext.Callback<NClob> CREATE_NCLOB_CALLBACK = new LobCreationContext.Callback<NClob>() {
@Override
public NClob executeOnConnection(Connection connection) throws SQLException {
return connection.createNClob();
}

View File

@ -39,8 +39,10 @@ public interface LobCreationContext {
* Perform whatever actions are necessary using the provided JDBC {@link Connection}.
*
* @param connection The JDBC {@link Connection}.
*
* @return The created LOB.
* @throws SQLException
*
* @throws SQLException Indicates trouble accessing the JDBC driver to create the LOB
*/
public T executeOnConnection(Connection connection) throws SQLException;
}
@ -49,6 +51,9 @@ public interface LobCreationContext {
* Execute the given callback, making sure it has access to a viable JDBC {@link Connection}.
*
* @param callback The callback to execute .
* @param <T> The Java type of the type of LOB being created. One of {@link java.sql.Blob},
* {@link java.sql.Clob}, {@link java.sql.NClob}
*
* @return The LOB created by the callback.
*/
public <T> T execute(Callback<T> callback);

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.engine.jdbc;
/**
* Marker interface for non-contextually created java.sql.NClob instances..
* <p/>

View File

@ -25,7 +25,6 @@ package org.hibernate.engine.jdbc;
import java.io.Reader;
import java.lang.reflect.Proxy;
import java.sql.Clob;
import java.sql.NClob;
import org.hibernate.internal.util.ClassLoaderHelper;
@ -40,6 +39,9 @@ import org.hibernate.internal.util.ClassLoaderHelper;
* @author Steve Ebersole
*/
public class NClobProxy extends ClobProxy {
/**
* The interfaces used to generate the proxy
*/
public static final Class[] PROXY_INTERFACES = new Class[] { NClob.class, NClobImplementer.class };
protected NClobProxy(String string) {
@ -58,15 +60,11 @@ public class NClobProxy extends ClobProxy {
* @return The generated proxy.
*/
public static NClob generateProxy(String string) {
return ( NClob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new ClobProxy( string )
);
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( string ) );
}
/**
* Generates a {@link Clob} proxy using a character reader of given length.
* Generates a {@link java.sql.NClob} proxy using a character reader of given length.
*
* @param reader The character reader
* @param length The length of the character reader
@ -74,11 +72,7 @@ public class NClobProxy extends ClobProxy {
* @return The generated proxy.
*/
public static NClob generateProxy(Reader reader, long length) {
return ( NClob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new ClobProxy( reader, length )
);
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( reader, length ) );
}
/**

View File

@ -37,6 +37,9 @@ import java.sql.NClob;
* @author Gail Badner
*/
public class NonContextualLobCreator extends AbstractLobCreator implements LobCreator {
/**
* Singleton access
*/
public static final NonContextualLobCreator INSTANCE = new NonContextualLobCreator();
private NonContextualLobCreator() {

View File

@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
@ -33,11 +34,17 @@ import java.io.Reader;
*/
public class ReaderInputStream extends InputStream {
private Reader reader;
/**
* Constructs a ReaderInputStream from a Reader
*
* @param reader The reader to expose as an InputStream
*/
public ReaderInputStream(Reader reader) {
this.reader = reader;
}
@Override
public int read() throws IOException {
return reader.read();
}

View File

@ -44,10 +44,12 @@ import org.hibernate.internal.util.ClassLoaderHelper;
* @author Gail Badner
*/
public class ResultSetWrapperProxy implements InvocationHandler {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, ResultSetWrapperProxy.class.getName());
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
ResultSetWrapperProxy.class.getName()
);
private static final Class[] PROXY_INTERFACES = new Class[] { ResultSet.class };
private static final SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper();
private static final SqlExceptionHelper SQL_EXCEPTION_HELPER = new SqlExceptionHelper();
private final ResultSet rs;
private final ColumnNameCache columnNameCache;
@ -65,7 +67,7 @@ public class ResultSetWrapperProxy implements InvocationHandler {
* @return The generated proxy.
*/
public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache) {
return ( ResultSet ) Proxy.newProxyInstance(
return (ResultSet) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new ResultSetWrapperProxy( resultSet, columnNameCache )
@ -90,26 +92,22 @@ public class ResultSetWrapperProxy implements InvocationHandler {
@SuppressWarnings( {"UnnecessaryBoxing"})
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ( "findColumn".equals( method.getName() ) ) {
return Integer.valueOf( findColumn( ( String ) args[0] ) );
return Integer.valueOf( findColumn( (String) args[0] ) );
}
if ( isFirstArgColumnLabel( method, args ) ) {
try {
int columnIndex = findColumn( ( String ) args[0] );
final int columnIndex = findColumn( (String) args[0] );
return invokeMethod(
locateCorrespondingColumnIndexMethod( method ), buildColumnIndexMethodArgs( args, columnIndex )
locateCorrespondingColumnIndexMethod( method ),
buildColumnIndexMethodArgs( args, columnIndex )
);
}
catch ( SQLException ex ) {
StringBuilder buf = new StringBuilder()
.append( "Exception getting column index for column: [" )
.append( args[0] )
.append( "].\nReverting to using: [" )
.append( args[0] )
.append( "] as first argument for method: [" )
.append( method )
.append( "]" );
sqlExceptionHelper.logExceptions( ex, buf.toString() );
final String msg = "Exception getting column index for column: [" + args[0] +
"].\nReverting to using: [" + args[0] +
"] as first argument for method: [" + method + "]";
SQL_EXCEPTION_HELPER.logExceptions( ex, msg );
}
catch ( NoSuchMethodException ex ) {
LOG.unableToSwitchToMethodUsingColumnIndex( method );
@ -158,7 +156,7 @@ public class ResultSetWrapperProxy implements InvocationHandler {
* @throws NoSuchMethodException Should never happen, but...
*/
private Method locateCorrespondingColumnIndexMethod(Method columnNameMethod) throws NoSuchMethodException {
Class actualParameterTypes[] = new Class[columnNameMethod.getParameterTypes().length];
final Class[] actualParameterTypes = new Class[columnNameMethod.getParameterTypes().length];
actualParameterTypes[0] = int.class;
System.arraycopy(
columnNameMethod.getParameterTypes(),
@ -172,13 +170,13 @@ public class ResultSetWrapperProxy implements InvocationHandler {
@SuppressWarnings( {"UnnecessaryBoxing"})
private Object[] buildColumnIndexMethodArgs(Object[] incomingArgs, int columnIndex) {
Object actualArgs[] = new Object[incomingArgs.length];
final Object[] actualArgs = new Object[incomingArgs.length];
actualArgs[0] = Integer.valueOf( columnIndex );
System.arraycopy( incomingArgs, 1, actualArgs, 1, incomingArgs.length - 1 );
return actualArgs;
}
private Object invokeMethod(Method method, Object args[]) throws Throwable {
private Object invokeMethod(Method method, Object[] args) throws Throwable {
try {
return method.invoke( rs, args );
}

View File

@ -43,7 +43,7 @@ import org.hibernate.internal.util.ClassLoaderHelper;
public class SerializableBlobProxy implements InvocationHandler, Serializable {
private static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, WrappedBlob.class, Serializable.class };
private transient final Blob blob;
private final transient Blob blob;
/**
* Builds a serializable {@link Blob} wrapper around the given {@link Blob}.
@ -55,6 +55,11 @@ public class SerializableBlobProxy implements InvocationHandler, Serializable {
this.blob = blob;
}
/**
* Access to the wrapped Blob reference
*
* @return The wrapped Blob reference
*/
public Blob getWrappedBlob() {
if ( blob == null ) {
throw new IllegalStateException( "Blobs may not be accessed after serialization" );
@ -88,11 +93,7 @@ public class SerializableBlobProxy implements InvocationHandler, Serializable {
* @return The generated proxy.
*/
public static Blob generateProxy(Blob blob) {
return ( Blob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new SerializableBlobProxy( blob )
);
return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableBlobProxy( blob ) );
}
/**

View File

@ -43,7 +43,7 @@ import org.hibernate.internal.util.ClassLoaderHelper;
public class SerializableClobProxy implements InvocationHandler, Serializable {
private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, WrappedClob.class, Serializable.class };
private transient final Clob clob;
private final transient Clob clob;
/**
* Builds a serializable {@link java.sql.Clob} wrapper around the given {@link java.sql.Clob}.
@ -55,6 +55,11 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
this.clob = clob;
}
/**
* Access to the wrapped Clob reference
*
* @return The wrapped Clob reference
*/
public Clob getWrappedClob() {
if ( clob == null ) {
throw new IllegalStateException( "Clobs may not be accessed after serialization" );
@ -87,11 +92,7 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
* @return The generated proxy.
*/
public static Clob generateProxy(Clob clob) {
return ( Clob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new SerializableClobProxy( clob )
);
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableClobProxy( clob ) );
}
/**

View File

@ -35,6 +35,16 @@ import java.sql.NClob;
public class SerializableNClobProxy extends SerializableClobProxy {
private static final Class[] PROXY_INTERFACES = new Class[] { NClob.class, WrappedNClob.class };
/**
* Deprecated.
*
* @param clob The possible NClob reference
*
* @return {@code true} if the the Clob is a NClob as well
*
* @deprecated ORM baselines on JDK 1.6, so optional support for NClob (JDK 1,6 addition) is no longer needed.
*/
@Deprecated
public static boolean isNClob(Clob clob) {
return NClob.class.isInstance( clob );
}
@ -57,11 +67,7 @@ public class SerializableNClobProxy extends SerializableClobProxy {
* @return The generated proxy.
*/
public static NClob generateProxy(NClob nclob) {
return ( NClob ) Proxy.newProxyInstance(
getProxyClassLoader(),
PROXY_INTERFACES,
new SerializableNClobProxy( nclob )
);
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableNClobProxy( nclob ) );
}
/**

View File

@ -35,14 +35,38 @@ import java.io.Writer;
* @author Steve Ebersole
*/
public class StreamUtils {
/**
* Default size to use for reading buffers.
*/
public static final int DEFAULT_CHUNK_SIZE = 1024;
/**
* Copy the inputStream to the outputStream. Uses a buffer of the default size ({@link #DEFAULT_CHUNK_SIZE}).
*
* @param inputStream The input stream to read
* @param outputStream The output stream to write to
*
* @return The number of bytes read
*
* @throws IOException If a problem occurred accessing either stream
*/
public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {
return copy( inputStream, outputStream, DEFAULT_CHUNK_SIZE );
}
/**
* Copy the inputStream to the outputStream using a buffer of the specified size
*
* @param inputStream The input stream to read
* @param outputStream The output stream to write to
* @param bufferSize The size of the buffer to use for reading
*
* @return The number of bytes read
*
* @throws IOException If a problem occurred accessing either stream
*/
public static long copy(InputStream inputStream, OutputStream outputStream, int bufferSize) throws IOException {
byte[] buffer = new byte[bufferSize];
final byte[] buffer = new byte[bufferSize];
long count = 0;
int n;
while ( -1 != ( n = inputStream.read( buffer ) ) ) {
@ -50,15 +74,35 @@ public class StreamUtils {
count += n;
}
return count;
}
/**
* Copy the reader to the writer. Uses a buffer of the default size ({@link #DEFAULT_CHUNK_SIZE}).
*
* @param reader The reader to read from
* @param writer The writer to write to
*
* @return The number of bytes read
*
* @throws IOException If a problem occurred accessing reader or writer
*/
public static long copy(Reader reader, Writer writer) throws IOException {
return copy( reader, writer, DEFAULT_CHUNK_SIZE );
}
/**
* Copy the reader to the writer using a buffer of the specified size
*
* @param reader The reader to read from
* @param writer The writer to write to
* @param bufferSize The size of the buffer to use for reading
*
* @return The number of bytes read
*
* @throws IOException If a problem occurred accessing either stream
*/
public static long copy(Reader reader, Writer writer, int bufferSize) throws IOException {
char[] buffer = new char[bufferSize];
final char[] buffer = new char[bufferSize];
long count = 0;
int n;
while ( -1 != ( n = reader.read( buffer ) ) ) {
@ -66,6 +110,8 @@ public class StreamUtils {
count += n;
}
return count;
}
private StreamUtils() {
}
}

View File

@ -26,12 +26,24 @@ package org.hibernate.engine.jdbc;
import java.sql.NClob;
/**
* Contract for {@link NClob} wrappers.
*
* @author Steve Ebersole
*/
public interface WrappedNClob extends WrappedClob {
/**
* {@inheritDoc}
*
* @deprecated Use {@link #getWrappedNClob()} instead
*/
@Override
@Deprecated
public NClob getWrappedClob();
/**
* Retrieve the wrapped {@link java.sql.Blob} reference
*
* @return The wrapped {@link java.sql.Blob} reference
*/
public NClob getWrappedNClob();
}

View File

@ -45,11 +45,14 @@ import org.hibernate.internal.CoreMessageLogger;
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
public abstract class AbstractBatchImpl implements Batch {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractBatchImpl.class.getName());
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
AbstractBatchImpl.class.getName()
);
private final BatchKey key;
private final JdbcCoordinator jdbcCoordinator;
private LinkedHashMap<String,PreparedStatement> statements = new LinkedHashMap<String,PreparedStatement>();
private LinkedHashSet<BatchObserver> observers = new LinkedHashSet<BatchObserver>();
@ -191,7 +194,7 @@ public abstract class AbstractBatchImpl implements Batch {
@Override
public void release() {
if ( getStatements() != null && !getStatements().isEmpty() ) {
if ( getStatements() != null && !getStatements().isEmpty() ) {
LOG.batchContainedStatementsOnRelease();
}
releaseStatements();

View File

@ -27,6 +27,8 @@ import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.jdbc.Expectation;
/**
* Normal implementation of BatchKey
*
* @author Steve Ebersole
*/
public class BasicBatchKey implements BatchKey {
@ -34,19 +36,12 @@ public class BasicBatchKey implements BatchKey {
private final int statementCount;
private final Expectation expectation;
// public BasicBatchKey(String comparison, int statementCount, Expectation expectation) {
// this.comparison = comparison;
// this.statementCount = statementCount;
// this.expectations = new Expectation[statementCount];
// Arrays.fill( this.expectations, expectation );
// }
//
// public BasicBatchKey(String comparison, Expectation... expectations) {
// this.comparison = comparison;
// this.statementCount = expectations.length;
// this.expectations = expectations;
// }
/**
* Constructs a BasicBatchKey
*
* @param comparison
* @param expectation
*/
public BasicBatchKey(String comparison, Expectation expectation) {
this.comparison = comparison;
this.statementCount = 1;
@ -72,7 +67,7 @@ public class BasicBatchKey implements BatchKey {
return false;
}
BasicBatchKey that = (BasicBatchKey) o;
final BasicBatchKey that = (BasicBatchKey) o;
if ( !comparison.equals( that.comparison ) ) {
return false;

View File

@ -42,23 +42,32 @@ import org.hibernate.service.spi.Configurable;
* @author Steve Ebersole
*/
public class BatchBuilderImpl implements BatchBuilder, Configurable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, BatchBuilderImpl.class.getName() );
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
BatchBuilderImpl.class.getName()
);
private int size;
/**
* Constructs a BatchBuilderImpl
*/
public BatchBuilderImpl() {
}
/**
* Constructs a BatchBuilderImpl
*/
public BatchBuilderImpl(int size) {
this.size = size;
}
@Override
public void configure(Map configurationValues) {
size = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, size );
}
public BatchBuilderImpl(int size) {
this.size = size;
}
@SuppressWarnings("UnusedDeclaration")
public void setJdbcBatchSize(int size) {
this.size = size;
}
@ -73,12 +82,14 @@ public class BatchBuilderImpl implements BatchBuilder, Configurable {
@Override
public String getManagementDomain() {
return null; // use Hibernate default domain
// use Hibernate default domain
return null;
}
@Override
public String getManagementServiceType() {
return null; // use Hibernate default scheme
// use Hibernate default scheme
return null;
}
@Override

View File

@ -39,7 +39,14 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
* @author Steve Ebersole
*/
public class BatchBuilderInitiator implements StandardServiceInitiator<BatchBuilder> {
/**
* Singleton access
*/
public static final BatchBuilderInitiator INSTANCE = new BatchBuilderInitiator();
/**
* Names the BatchBuilder implementation to use.
*/
public static final String BUILDER = "hibernate.jdbc.batch.builder";
@Override

View File

@ -40,8 +40,10 @@ import org.hibernate.internal.CoreMessageLogger;
* @author Steve Ebersole
*/
public class BatchingBatch extends AbstractBatchImpl {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, BatchingBatch.class.getName() );
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
BatchingBatch.class.getName()
);
// IMPL NOTE : Until HHH-5797 is fixed, there will only be 1 statement in a batch
@ -49,6 +51,13 @@ public class BatchingBatch extends AbstractBatchImpl {
private int batchPosition;
private int statementPosition;
/**
* Constructs a BatchingBatch
*
* @param key The batch key
* @param jdbcCoordinator The JDBC jdbcCoordinator
* @param batchSize The batch size.
*/
public BatchingBatch(
BatchKey key,
JdbcCoordinator jdbcCoordinator,
@ -125,7 +134,7 @@ public class BatchingBatch extends AbstractBatchImpl {
}
private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
int numberOfRowCounts = rowCounts.length;
final int numberOfRowCounts = rowCounts.length;
if ( numberOfRowCounts != batchPosition ) {
LOG.unexpectedRowCounts();
}
@ -133,4 +142,4 @@ public class BatchingBatch extends AbstractBatchImpl {
getKey().getExpectation().verifyOutcome( rowCounts[i], ps, i );
}
}
}
}

View File

@ -39,8 +39,10 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole
*/
public class NonBatchingBatch extends AbstractBatchImpl {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, NonBatchingBatch.class.getName() );
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
NonBatchingBatch.class.getName()
);
private JdbcCoordinator jdbcCoordinator;

View File

@ -0,0 +1,4 @@
/**
* Internals for JDBC batching support.
*/
package org.hibernate.engine.jdbc.batch.internal;

View File

@ -0,0 +1,4 @@
/**
* Defines contracts for JDBC batching support.
*/
package org.hibernate.engine.jdbc.batch.spi;

View File

@ -52,14 +52,29 @@ import org.jboss.logging.Logger;
* @author Brett Meyer
*/
public class ConnectionProviderInitiator implements StandardServiceInitiator<ConnectionProvider> {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
ConnectionProviderInitiator.class.getName()
);
/**
* Singleton access
*/
public static final ConnectionProviderInitiator INSTANCE = new ConnectionProviderInitiator();
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
ConnectionProviderInitiator.class.getName());
/**
* The strategy for c3p0 connection pooling
*/
public static final String C3P0_STRATEGY = "c3p0";
/**
* The strategy for proxool connection pooling
*/
public static final String PROXOOL_STRATEGY = "proxool";
/**
* No idea. Is this even still used?
*/
public static final String INJECTION_DATA = "hibernate.connection_provider.injection_data";
// mapping from legacy connection provider name to actual
@ -99,7 +114,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
final StrategySelector strategySelector = registry.getService( StrategySelector.class );
ConnectionProvider connectionProvider = null;
String providerName = getConfiguredConnectionProviderName( configurationValues );
final String providerName = getConfiguredConnectionProviderName( configurationValues );
if ( providerName != null ) {
connectionProvider = instantiateExplicitConnectionProvider( providerName, strategySelector );
}
@ -126,7 +141,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
}
if ( connectionProvider == null ) {
LOG.noAppropriateConnectionProvider();
LOG.noAppropriateConnectionProvider();
connectionProvider = new UserSuppliedConnectionProviderImpl();
}
@ -138,11 +153,11 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
connectionProvider,
new BeanInfoHelper.BeanInfoDelegate() {
public void processBeanInfo(BeanInfo beanInfo) throws Exception {
PropertyDescriptor[] descritors = beanInfo.getPropertyDescriptors();
for ( int i = 0, size = descritors.length; i < size; i++ ) {
String propertyName = descritors[i].getName();
final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for ( PropertyDescriptor descriptor : descriptors ) {
final String propertyName = descriptor.getName();
if ( injectionData.containsKey( propertyName ) ) {
Method method = descritors[i].getWriteMethod();
final Method method = descriptor.getWriteMethod();
method.invoke(
theConnectionProvider,
injectionData.get( propertyName )
@ -158,10 +173,10 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
}
private String getConfiguredConnectionProviderName( Map configurationValues ) {
String providerName = ( String ) configurationValues.get( Environment.CONNECTION_PROVIDER );
String providerName = (String) configurationValues.get( Environment.CONNECTION_PROVIDER );
if ( LEGACY_CONNECTION_PROVIDER_MAPPING.containsKey( providerName ) ) {
String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName );
LOG.providerClassDeprecated(providerName, actualProviderName);
final String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName );
LOG.providerClassDeprecated( providerName, actualProviderName );
providerName = actualProviderName;
}
return providerName;
@ -171,7 +186,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
String providerName,
StrategySelector strategySelector) {
try {
LOG.instantiatingExplicitConnectionProvider( providerName );
LOG.instantiatingExplicitConnectionProvider( providerName );
// This relies on selectStrategyImplementor trying
// classLoaderService.classForName( name ).
// TODO: Maybe we shouldn't rely on that here and do it manually?
@ -187,7 +202,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
return strategySelector.selectStrategyImplementor( ConnectionProvider.class, C3P0_STRATEGY ).newInstance();
}
catch ( Exception e ) {
LOG.c3p0ProviderClassNotFound(C3P0_STRATEGY);
LOG.c3p0ProviderClassNotFound(C3P0_STRATEGY);
return null;
}
}
@ -207,7 +222,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
return strategySelector.selectStrategyImplementor( ConnectionProvider.class, PROXOOL_STRATEGY ).newInstance();
}
catch ( Exception e ) {
LOG.proxoolProviderClassNotFound(PROXOOL_STRATEGY);
LOG.proxoolProviderClassNotFound( PROXOOL_STRATEGY );
return null;
}
}
@ -233,7 +248,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
* @return The connection properties.
*/
public static Properties getConnectionProperties(Map<?,?> properties) {
Properties result = new Properties();
final Properties result = new Properties();
for ( Map.Entry entry : properties.entrySet() ) {
if ( ! ( String.class.isInstance( entry.getKey() ) ) || ! String.class.isInstance( entry.getValue() ) ) {
continue;

View File

@ -49,7 +49,6 @@ import org.hibernate.service.spi.Stoppable;
* @author Steve Ebersole
*/
public class DatasourceConnectionProviderImpl implements ConnectionProvider, Configurable, Stoppable {
private DataSource dataSource;
private String user;
private String pass;
@ -67,6 +66,7 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
}
@InjectService( required = false )
@SuppressWarnings("UnusedDeclaration")
public void setJndiService(JndiService jndiService) {
this.jndiService = jndiService;
}
@ -93,9 +93,7 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
}
}
/**
* {@inheritDoc}
*/
@Override
public void configure(Map configValues) {
if ( this.dataSource == null ) {
final Object dataSource = configValues.get( Environment.DATASOURCE );
@ -126,14 +124,13 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
available = true;
}
@Override
public void stop() {
available = false;
dataSource = null;
}
/**
* {@inheritDoc}
*/
@Override
public Connection getConnection() throws SQLException {
if ( !available ) {
throw new HibernateException( "Provider is closed!" );
@ -141,16 +138,12 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
return useCredentials ? dataSource.getConnection( user, pass ) : dataSource.getConnection();
}
/**
* {@inheritDoc}
*/
@Override
public void closeConnection(Connection connection) throws SQLException {
connection.close();
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsAggressiveRelease() {
return true;
}

View File

@ -95,10 +95,11 @@ public class DriverManagerConnectionProviderImpl
}
}
@Override
public void configure(Map configurationValues) {
LOG.usingHibernateBuiltInConnectionPool();
String driverClassName = (String) configurationValues.get( AvailableSettings.DRIVER );
final String driverClassName = (String) configurationValues.get( AvailableSettings.DRIVER );
if ( driverClassName == null ) {
LOG.jdbcDriverNotSpecified( AvailableSettings.DRIVER );
}
@ -131,19 +132,21 @@ public class DriverManagerConnectionProviderImpl
}
}
poolSize = ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 ); // default pool size 20
// default pool size 20
poolSize = ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 );
LOG.hibernateConnectionPoolSize( poolSize );
autocommit = ConfigurationHelper.getBoolean( AvailableSettings.AUTOCOMMIT, configurationValues );
LOG.autoCommitMode( autocommit );
isolation = ConfigurationHelper.getInteger( AvailableSettings.ISOLATION, configurationValues );
if ( isolation != null )
if ( isolation != null ) {
LOG.jdbcIsolationLevel( Environment.isolationLevelToString( isolation.intValue() ) );
}
url = (String) configurationValues.get( AvailableSettings.URL );
if ( url == null ) {
String msg = LOG.jdbcUrlNotSpecified( AvailableSettings.URL );
final String msg = LOG.jdbcUrlNotSpecified( AvailableSettings.URL );
LOG.error( msg );
throw new HibernateException( msg );
}
@ -152,12 +155,15 @@ public class DriverManagerConnectionProviderImpl
LOG.usingDriver( driverClassName, url );
// if debug level is enabled, then log the password, otherwise mask it
if ( LOG.isDebugEnabled() )
if ( LOG.isDebugEnabled() ) {
LOG.connectionProperties( connectionProps );
else
}
else {
LOG.connectionProperties( ConfigurationHelper.maskOut( connectionProps, "password" ) );
}
}
@Override
public void stop() {
LOG.cleaningUpConnectionPool( url );
@ -173,16 +179,21 @@ public class DriverManagerConnectionProviderImpl
stopped = true;
}
@Override
public Connection getConnection() throws SQLException {
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) LOG.tracev( "Total checked-out connections: {0}", checkedOut.intValue() );
if ( traceEnabled ) {
LOG.tracev( "Total checked-out connections: {0}", checkedOut.intValue() );
}
// essentially, if we have available connections in the pool, use one...
synchronized (pool) {
if ( !pool.isEmpty() ) {
int last = pool.size() - 1;
if ( traceEnabled ) LOG.tracev( "Using pooled JDBC connection, pool size: {0}", last );
Connection pooled = pool.remove( last );
if ( traceEnabled ) {
LOG.tracev( "Using pooled JDBC connection, pool size: {0}", last );
}
final Connection pooled = pool.remove( last );
if ( isolation != null ) {
pooled.setTransactionIsolation( isolation.intValue() );
}
@ -196,9 +207,11 @@ public class DriverManagerConnectionProviderImpl
// otherwise we open a new connection...
final boolean debugEnabled = LOG.isDebugEnabled();
if ( debugEnabled ) LOG.debug( "Opening new JDBC connection" );
if ( debugEnabled ) {
LOG.debug( "Opening new JDBC connection" );
}
Connection conn;
final Connection conn;
if ( driver != null ) {
// If a Driver is available, completely circumvent
// DriverManager#getConnection. It attempts to double check
@ -215,7 +228,7 @@ public class DriverManagerConnectionProviderImpl
conn.setTransactionIsolation( isolation.intValue() );
}
if ( conn.getAutoCommit() != autocommit ) {
conn.setAutoCommit(autocommit);
conn.setAutoCommit( autocommit );
}
if ( debugEnabled ) {
@ -226,15 +239,18 @@ public class DriverManagerConnectionProviderImpl
return conn;
}
@Override
public void closeConnection(Connection conn) throws SQLException {
checkedOut.decrementAndGet();
final boolean traceEnabled = LOG.isTraceEnabled();
// add to the pool if the max size is not yet reached.
synchronized ( pool ) {
int currentSize = pool.size();
final int currentSize = pool.size();
if ( currentSize < poolSize ) {
if ( traceEnabled ) LOG.tracev( "Returning connection to pool, pool size: {0}", ( currentSize + 1 ) );
if ( traceEnabled ) {
LOG.tracev( "Returning connection to pool, pool size: {0}", ( currentSize + 1 ) );
}
pool.add( conn );
return;
}
@ -252,6 +268,7 @@ public class DriverManagerConnectionProviderImpl
super.finalize();
}
@Override
public boolean supportsAggressiveRelease() {
return false;
}

View File

@ -38,12 +38,18 @@ import org.hibernate.service.spi.ServiceException;
import org.hibernate.service.spi.ServiceRegistryImplementor;
/**
* A service initiator for the MultiTenantConnectionProvider service
*
* @author Steve Ebersole
*/
public class MultiTenantConnectionProviderInitiator implements StandardServiceInitiator<MultiTenantConnectionProvider> {
public static final MultiTenantConnectionProviderInitiator INSTANCE = new MultiTenantConnectionProviderInitiator();
private static final Logger log = Logger.getLogger( MultiTenantConnectionProviderInitiator.class );
/**
* Singleton access
*/
public static final MultiTenantConnectionProviderInitiator INSTANCE = new MultiTenantConnectionProviderInitiator();
@Override
public Class<MultiTenantConnectionProvider> getServiceInitiated() {
return MultiTenantConnectionProvider.class;
@ -55,6 +61,7 @@ public class MultiTenantConnectionProviderInitiator implements StandardServiceIn
final MultiTenancyStrategy strategy = MultiTenancyStrategy.determineMultiTenancyStrategy( configurationValues );
if ( strategy == MultiTenancyStrategy.NONE || strategy == MultiTenancyStrategy.DISCRIMINATOR ) {
// nothing to do, but given the separate hierarchies have to handle this here.
return null;
}
final Object configValue = configurationValues.get( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER );

View File

@ -55,23 +55,17 @@ public class UserSuppliedConnectionProviderImpl implements ConnectionProvider {
}
}
/**
* {@inheritDoc}
*/
@Override
public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
}
/**
* {@inheritDoc}
*/
@Override
public void closeConnection(Connection conn) throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsAggressiveRelease() {
return false;
}

View File

@ -0,0 +1,4 @@
/**
* Internals for accessing JDBC Connections
*/
package org.hibernate.engine.jdbc.connections.internal;

View File

@ -25,7 +25,6 @@ package org.hibernate.engine.jdbc.connections.spi;
import java.sql.Connection;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.service.Service;
import org.hibernate.service.spi.Wrapped;
@ -46,7 +45,7 @@ public interface ConnectionProvider extends Service, Wrapped {
* @return The obtained JDBC connection
*
* @throws SQLException Indicates a problem opening a connection
* @throws HibernateException Indicates a problem otherwise obtaining a connection.
* @throws org.hibernate.HibernateException Indicates a problem otherwise obtaining a connection.
*/
public Connection getConnection() throws SQLException;
@ -56,7 +55,7 @@ public interface ConnectionProvider extends Service, Wrapped {
* @param conn The JDBC connection to release
*
* @throws SQLException Indicates a problem closing the connection
* @throws HibernateException Indicates a problem otherwise releasing a connection.
* @throws org.hibernate.HibernateException Indicates a problem otherwise releasing a connection.
*/
public void closeConnection(Connection conn) throws SQLException;

View File

@ -56,6 +56,9 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl
implements ServiceRegistryAwareService, Stoppable {
/**
* Identifies the DataSource name to use for {@link #selectAnyDataSource} handling
*/
public static final String TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY = "hibernate.multi_tenant.datasource.identifier_for_any";
private Map<String,DataSource> dataSourceMap;
@ -100,13 +103,13 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl
throw new HibernateException( "Could not locate JndiService from DataSourceBasedMultiTenantConnectionProviderImpl" );
}
Object namedObject = jndiService.locate( jndiName );
final Object namedObject = jndiService.locate( jndiName );
if ( namedObject == null ) {
throw new HibernateException( "JNDI name [" + jndiName + "] could not be resolved" );
}
if ( DataSource.class.isInstance( namedObject ) ) {
int loc = jndiName.lastIndexOf( "/" );
final int loc = jndiName.lastIndexOf( "/" );
this.baseJndiNamespace = jndiName.substring( 0, loc );
this.tenantIdentifierForAny = jndiName.substring( loc + 1 );
dataSourceMap().put( tenantIdentifierForAny, (DataSource) namedObject );

View File

@ -30,6 +30,9 @@ import org.hibernate.service.Service;
import org.hibernate.service.spi.Wrapped;
/**
* A specialized Connection provider contract used when the application is using multi-tenancy support requiring
* tenant aware connections.
*
* @author Steve Ebersole
*/
public interface MultiTenantConnectionProvider extends Service, Wrapped {

View File

@ -0,0 +1,4 @@
/**
* Defines contracts for accessing JDBC Connections
*/
package org.hibernate.engine.jdbc.connections.spi;

View File

@ -0,0 +1,4 @@
/**
* Support for various aspects of JDBC interaction
*/
package org.hibernate.engine.jdbc;

View File

@ -202,7 +202,10 @@
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<module name="MemberName" />
<!--
The org.hibernate.engine.spi.ManagedEntity method names (prefixed with '&&_') muck with this
<module name="MethodName" />
-->
<module name="MethodTypeParameterName" />
<module name="PackageName" />
<module name="ParameterName" />