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

View File

@ -56,6 +56,15 @@ public enum OptimisticLockStyle {
return oldCode; 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) { public static OptimisticLockStyle interpretOldCode(int oldCode) {
switch ( oldCode ) { switch ( oldCode ) {
case -1: { case -1: {

View File

@ -33,10 +33,47 @@ import org.hibernate.service.Service;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ConfigurationService extends Service { 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(); 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); 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); 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); 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 expected The type of instance expected to return.
* @param candidate The candidate object to be casted. * @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. * @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); 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> { 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); public T convert(Object value);
} }
} }

View File

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

View File

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

View File

@ -89,6 +89,8 @@ public final class ForeignKeys {
* *
* @param value An entity attribute value * @param value An entity attribute value
* @param type An entity attribute type * @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) private Object nullifyTransientReferences(final Object value, final Type type)
throws HibernateException { throws HibernateException {

View File

@ -33,12 +33,21 @@ import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.AssociationType; import org.hibernate.type.AssociationType;
/** /**
* Helper for dealing with joins.
*
* @author Gavin King * @author Gavin King
*/ */
public final class JoinHelper { public final class JoinHelper {
/** /**
* Get the aliased columns of the owning entity which are to * Get the qualified (prefixed by alias) names of the columns of the owning entity which are to be used in the join
* 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( public static String[] getAliasedLHSColumnNames(
AssociationType type, AssociationType type,
@ -50,8 +59,14 @@ public final class JoinHelper {
} }
/** /**
* Get the columns of the owning entity which are to * Get the unqualified names of the columns of the owning entity which are to be used in the join.
* 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( public static String[] getLHSColumnNames(
AssociationType type, 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( public static String[] getAliasedLHSColumnNames(
AssociationType associationType, AssociationType associationType,
@ -76,7 +102,7 @@ public final class JoinHelper {
return StringHelper.qualify( columnQualifier, lhsPersister.getIdentifierColumnNames() ); return StringHelper.qualify( columnQualifier, lhsPersister.getIdentifierColumnNames() );
} }
else { else {
String propertyName = associationType.getLHSPropertyName(); final String propertyName = associationType.getLHSPropertyName();
if ( propertyName == null ) { if ( propertyName == null ) {
return ArrayHelper.slice( return ArrayHelper.slice(
toColumns( lhsPersister, columnQualifier, propertyIndex ), toColumns( lhsPersister, columnQualifier, propertyIndex ),

View File

@ -404,7 +404,7 @@ public class NaturalIdXrefDelegate {
} }
final CachedNaturalId other = (CachedNaturalId) obj; 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) { private boolean isSame(Object[] otherValues) {

View File

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

View File

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

View File

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

View File

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

View File

@ -82,7 +82,7 @@ public class UnsavedValueFactory {
if ( unsavedValue == null ) { if ( unsavedValue == null ) {
if ( identifierGetter != null && constructor != null ) { if ( identifierGetter != null && constructor != null ) {
// use the id value of a newly instantiated instance as the unsaved-value // 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 ); return new IdentifierValue( defaultValue );
} }
else if ( identifierGetter != null && (identifierType instanceof PrimitiveType) ) { 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 static final Class[] PROXY_INTERFACES = new Class[] { Blob.class, BlobImplementer.class };
private BinaryStream binaryStream; private BinaryStream binaryStream;
private boolean needsReset = false; private boolean needsReset;
/** /**
* Constructor used to build {@link Blob} from byte array. * Constructor used to build {@link Blob} from byte array.
@ -75,7 +75,7 @@ public class BlobProxy implements InvocationHandler {
} }
private InputStream getStream() throws SQLException { private InputStream getStream() throws SQLException {
InputStream stream = binaryStream.getInputStream(); final InputStream stream = binaryStream.getInputStream();
try { try {
if ( needsReset ) { if ( needsReset ) {
stream.reset(); stream.reset();
@ -92,8 +92,7 @@ public class BlobProxy implements InvocationHandler {
* {@inheritDoc} * {@inheritDoc}
* *
* @throws UnsupportedOperationException if any methods other than * @throws UnsupportedOperationException if any methods other than
* {@link Blob#length}, {@link Blob#getUnderlyingStream}, * {@link Blob#length}, {@link Blob#getBinaryStream}, {@link Blob#getBytes}, {@link Blob#free},
* {@link Blob#getBinaryStream}, {@link Blob#getBytes}, {@link Blob#free},
* or toString/equals/hashCode are invoked. * or toString/equals/hashCode are invoked.
*/ */
@Override @Override
@ -120,7 +119,7 @@ public class BlobProxy implements InvocationHandler {
if ( start > getLength() ) { if ( start > getLength() ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + 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 ) { if ( length < 0 ) {
// java docs specifically say for getBinaryStream(long,int) that the start+length must not exceed the // 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. // 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 ( "getBytes".equals( methodName ) ) {
if ( argCount == 2 ) { if ( argCount == 2 ) {
long start = (Long) args[0]; final long start = (Long) args[0];
if ( start < 1 ) { if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." ); 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 ) { if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." ); 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. * @return The generated proxy.
*/ */
public static Blob generateProxy(byte[] bytes) { public static Blob generateProxy(byte[] bytes) {
return ( Blob ) Proxy.newProxyInstance( return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( bytes ) );
getProxyClassLoader(),
PROXY_INTERFACES,
new BlobProxy( bytes )
);
} }
/** /**
@ -183,11 +178,7 @@ public class BlobProxy implements InvocationHandler {
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Blob generateProxy(InputStream stream, long length) { public static Blob generateProxy(InputStream stream, long length) {
return ( Blob ) Proxy.newProxyInstance( return (Blob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new BlobProxy( stream, length ) );
getProxyClassLoader(),
PROXY_INTERFACES,
new BlobProxy( stream, length )
);
} }
/** /**

View File

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

View File

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

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * 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 * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * 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, * 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 * copy, or redistribute it subject to the terms and conditions of the GNU
@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc; package org.hibernate.engine.jdbc;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map; import java.util.Map;
@ -33,22 +34,40 @@ import java.util.concurrent.ConcurrentHashMap;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ColumnNameCache { public class ColumnNameCache {
public static final float LOAD_FACTOR = .75f; private static final float LOAD_FACTOR = .75f;
private final Map<String, Integer> columnNameToIndexCache; private final Map<String, Integer> columnNameToIndexCache;
/**
* Constructs a ColumnNameCache
*
* @param columnCount The number of columns to be cached.
*/
public ColumnNameCache(int columnCount) { public ColumnNameCache(int columnCount) {
// should *not* need to grow beyond the size of the total number of columns in the rs // 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 { public int getIndexForColumnName(String columnName, ResultSet rs) throws SQLException {
Integer cached = columnNameToIndexCache.get( columnName ); final Integer cached = columnNameToIndexCache.get( columnName );
if ( cached != null ) { if ( cached != null ) {
return cached; return cached;
} }
else { else {
int index = rs.findColumn( columnName ); final int index = rs.findColumn( columnName );
columnNameToIndexCache.put( columnName, index); columnNameToIndexCache.put( columnName, index);
return index; return index;
} }

View File

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

View File

@ -39,8 +39,10 @@ public interface LobCreationContext {
* Perform whatever actions are necessary using the provided JDBC {@link Connection}. * Perform whatever actions are necessary using the provided JDBC {@link Connection}.
* *
* @param connection The JDBC {@link Connection}. * @param connection The JDBC {@link Connection}.
*
* @return The created LOB. * @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; 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}. * Execute the given callback, making sure it has access to a viable JDBC {@link Connection}.
* *
* @param callback The callback to execute . * @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. * @return The LOB created by the callback.
*/ */
public <T> T execute(Callback<T> callback); public <T> T execute(Callback<T> callback);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,7 +43,7 @@ import org.hibernate.internal.util.ClassLoaderHelper;
public class SerializableClobProxy implements InvocationHandler, Serializable { public class SerializableClobProxy implements InvocationHandler, Serializable {
private static final Class[] PROXY_INTERFACES = new Class[] { Clob.class, WrappedClob.class, Serializable.class }; 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}. * 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; this.clob = clob;
} }
/**
* Access to the wrapped Clob reference
*
* @return The wrapped Clob reference
*/
public Clob getWrappedClob() { public Clob getWrappedClob() {
if ( clob == null ) { if ( clob == null ) {
throw new IllegalStateException( "Clobs may not be accessed after serialization" ); throw new IllegalStateException( "Clobs may not be accessed after serialization" );
@ -87,11 +92,7 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
* @return The generated proxy. * @return The generated proxy.
*/ */
public static Clob generateProxy(Clob clob) { public static Clob generateProxy(Clob clob) {
return ( Clob ) Proxy.newProxyInstance( return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableClobProxy( clob ) );
getProxyClassLoader(),
PROXY_INTERFACES,
new SerializableClobProxy( clob )
);
} }
/** /**

View File

@ -35,6 +35,16 @@ import java.sql.NClob;
public class SerializableNClobProxy extends SerializableClobProxy { public class SerializableNClobProxy extends SerializableClobProxy {
private static final Class[] PROXY_INTERFACES = new Class[] { NClob.class, WrappedNClob.class }; 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) { public static boolean isNClob(Clob clob) {
return NClob.class.isInstance( clob ); return NClob.class.isInstance( clob );
} }
@ -57,11 +67,7 @@ public class SerializableNClobProxy extends SerializableClobProxy {
* @return The generated proxy. * @return The generated proxy.
*/ */
public static NClob generateProxy(NClob nclob) { public static NClob generateProxy(NClob nclob) {
return ( NClob ) Proxy.newProxyInstance( return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new SerializableNClobProxy( nclob ) );
getProxyClassLoader(),
PROXY_INTERFACES,
new SerializableNClobProxy( nclob )
);
} }
/** /**

View File

@ -35,14 +35,38 @@ import java.io.Writer;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class StreamUtils { public class StreamUtils {
/**
* Default size to use for reading buffers.
*/
public static final int DEFAULT_CHUNK_SIZE = 1024; 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 { public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {
return copy( inputStream, outputStream, DEFAULT_CHUNK_SIZE ); 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 { 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; long count = 0;
int n; int n;
while ( -1 != ( n = inputStream.read( buffer ) ) ) { while ( -1 != ( n = inputStream.read( buffer ) ) ) {
@ -50,15 +74,35 @@ public class StreamUtils {
count += n; count += n;
} }
return count; 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 { public static long copy(Reader reader, Writer writer) throws IOException {
return copy( reader, writer, DEFAULT_CHUNK_SIZE ); 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 { 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; long count = 0;
int n; int n;
while ( -1 != ( n = reader.read( buffer ) ) ) { while ( -1 != ( n = reader.read( buffer ) ) ) {
@ -66,6 +110,8 @@ public class StreamUtils {
count += n; count += n;
} }
return count; return count;
}
private StreamUtils() {
} }
} }

View File

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

View File

@ -45,11 +45,14 @@ import org.hibernate.internal.CoreMessageLogger;
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/ */
public abstract class AbstractBatchImpl implements Batch { public abstract class AbstractBatchImpl implements Batch {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractBatchImpl.class.getName()); CoreMessageLogger.class,
AbstractBatchImpl.class.getName()
);
private final BatchKey key; private final BatchKey key;
private final JdbcCoordinator jdbcCoordinator; private final JdbcCoordinator jdbcCoordinator;
private LinkedHashMap<String,PreparedStatement> statements = new LinkedHashMap<String,PreparedStatement>(); private LinkedHashMap<String,PreparedStatement> statements = new LinkedHashMap<String,PreparedStatement>();
private LinkedHashSet<BatchObserver> observers = new LinkedHashSet<BatchObserver>(); private LinkedHashSet<BatchObserver> observers = new LinkedHashSet<BatchObserver>();

View File

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

View File

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

View File

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

View File

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

View File

@ -39,8 +39,10 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NonBatchingBatch extends AbstractBatchImpl { public class NonBatchingBatch extends AbstractBatchImpl {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, NonBatchingBatch.class.getName() ); CoreMessageLogger.class,
NonBatchingBatch.class.getName()
);
private JdbcCoordinator jdbcCoordinator; 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 * @author Brett Meyer
*/ */
public class ConnectionProviderInitiator implements StandardServiceInitiator<ConnectionProvider> { 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(); 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"; public static final String C3P0_STRATEGY = "c3p0";
/**
* The strategy for proxool connection pooling
*/
public static final String PROXOOL_STRATEGY = "proxool"; 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"; public static final String INJECTION_DATA = "hibernate.connection_provider.injection_data";
// mapping from legacy connection provider name to actual // 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 ); final StrategySelector strategySelector = registry.getService( StrategySelector.class );
ConnectionProvider connectionProvider = null; ConnectionProvider connectionProvider = null;
String providerName = getConfiguredConnectionProviderName( configurationValues ); final String providerName = getConfiguredConnectionProviderName( configurationValues );
if ( providerName != null ) { if ( providerName != null ) {
connectionProvider = instantiateExplicitConnectionProvider( providerName, strategySelector ); connectionProvider = instantiateExplicitConnectionProvider( providerName, strategySelector );
} }
@ -138,11 +153,11 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
connectionProvider, connectionProvider,
new BeanInfoHelper.BeanInfoDelegate() { new BeanInfoHelper.BeanInfoDelegate() {
public void processBeanInfo(BeanInfo beanInfo) throws Exception { public void processBeanInfo(BeanInfo beanInfo) throws Exception {
PropertyDescriptor[] descritors = beanInfo.getPropertyDescriptors(); final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for ( int i = 0, size = descritors.length; i < size; i++ ) { for ( PropertyDescriptor descriptor : descriptors ) {
String propertyName = descritors[i].getName(); final String propertyName = descriptor.getName();
if ( injectionData.containsKey( propertyName ) ) { if ( injectionData.containsKey( propertyName ) ) {
Method method = descritors[i].getWriteMethod(); final Method method = descriptor.getWriteMethod();
method.invoke( method.invoke(
theConnectionProvider, theConnectionProvider,
injectionData.get( propertyName ) injectionData.get( propertyName )
@ -158,10 +173,10 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
} }
private String getConfiguredConnectionProviderName( Map configurationValues ) { 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 ) ) { if ( LEGACY_CONNECTION_PROVIDER_MAPPING.containsKey( providerName ) ) {
String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName ); final String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName );
LOG.providerClassDeprecated(providerName, actualProviderName); LOG.providerClassDeprecated( providerName, actualProviderName );
providerName = actualProviderName; providerName = actualProviderName;
} }
return providerName; return providerName;
@ -207,7 +222,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
return strategySelector.selectStrategyImplementor( ConnectionProvider.class, PROXOOL_STRATEGY ).newInstance(); return strategySelector.selectStrategyImplementor( ConnectionProvider.class, PROXOOL_STRATEGY ).newInstance();
} }
catch ( Exception e ) { catch ( Exception e ) {
LOG.proxoolProviderClassNotFound(PROXOOL_STRATEGY); LOG.proxoolProviderClassNotFound( PROXOOL_STRATEGY );
return null; return null;
} }
} }
@ -233,7 +248,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
* @return The connection properties. * @return The connection properties.
*/ */
public static Properties getConnectionProperties(Map<?,?> properties) { public static Properties getConnectionProperties(Map<?,?> properties) {
Properties result = new Properties(); final Properties result = new Properties();
for ( Map.Entry entry : properties.entrySet() ) { for ( Map.Entry entry : properties.entrySet() ) {
if ( ! ( String.class.isInstance( entry.getKey() ) ) || ! String.class.isInstance( entry.getValue() ) ) { if ( ! ( String.class.isInstance( entry.getKey() ) ) || ! String.class.isInstance( entry.getValue() ) ) {
continue; continue;

View File

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

View File

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

View File

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

View File

@ -55,23 +55,17 @@ public class UserSuppliedConnectionProviderImpl implements ConnectionProvider {
} }
} }
/** @Override
* {@inheritDoc}
*/
public Connection getConnection() throws SQLException { public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" ); throw new UnsupportedOperationException( "The application must supply JDBC connections" );
} }
/** @Override
* {@inheritDoc}
*/
public void closeConnection(Connection conn) throws SQLException { public void closeConnection(Connection conn) throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" ); throw new UnsupportedOperationException( "The application must supply JDBC connections" );
} }
/** @Override
* {@inheritDoc}
*/
public boolean supportsAggressiveRelease() { public boolean supportsAggressiveRelease() {
return false; 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.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.service.Service; import org.hibernate.service.Service;
import org.hibernate.service.spi.Wrapped; import org.hibernate.service.spi.Wrapped;
@ -46,7 +45,7 @@ public interface ConnectionProvider extends Service, Wrapped {
* @return The obtained JDBC connection * @return The obtained JDBC connection
* *
* @throws SQLException Indicates a problem opening a 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; public Connection getConnection() throws SQLException;
@ -56,7 +55,7 @@ public interface ConnectionProvider extends Service, Wrapped {
* @param conn The JDBC connection to release * @param conn The JDBC connection to release
* *
* @throws SQLException Indicates a problem closing the connection * @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; public void closeConnection(Connection conn) throws SQLException;

View File

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

View File

@ -30,6 +30,9 @@ import org.hibernate.service.Service;
import org.hibernate.service.spi.Wrapped; 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 * @author Steve Ebersole
*/ */
public interface MultiTenantConnectionProvider extends Service, Wrapped { 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="LocalFinalVariableName" />
<module name="LocalVariableName" /> <module name="LocalVariableName" />
<module name="MemberName" /> <module name="MemberName" />
<!--
The org.hibernate.engine.spi.ManagedEntity method names (prefixed with '&&_') muck with this
<module name="MethodName" /> <module name="MethodName" />
-->
<module name="MethodTypeParameterName" /> <module name="MethodTypeParameterName" />
<module name="PackageName" /> <module name="PackageName" />
<module name="ParameterName" /> <module name="ParameterName" />