HHH-8159 - Apply fixups indicated by analysis tools
This commit is contained in:
parent
0edd7b75b8
commit
3b8320da7e
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 ),
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) ) {
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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/>
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Internals for JDBC batching support.
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.batch.internal;
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Defines contracts for JDBC batching support.
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.batch.spi;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Internals for accessing JDBC Connections
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.connections.internal;
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Defines contracts for accessing JDBC Connections
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc.connections.spi;
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Support for various aspects of JDBC interaction
|
||||||
|
*/
|
||||||
|
package org.hibernate.engine.jdbc;
|
|
@ -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" />
|
||||||
|
|
Loading…
Reference in New Issue