package reorg for some Blob/Clob-related types

stop using Proxy to implement Clob/NClob
(this is more consistent with BlobProxy)

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-11-04 12:00:20 +01:00
parent d4b2d0fb9f
commit 35b97a040e
37 changed files with 364 additions and 347 deletions

View File

@ -1,49 +0,0 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.NClob;
/**
* Convenient base class for proxy-based {@link LobCreator} for handling wrapping.
*
* @author Steve Ebersole
*/
public abstract class AbstractLobCreator implements LobCreator {
@Override
public Blob wrap(Blob blob) {
return SerializableBlobProxy.generateProxy( blob );
}
@Override
public Clob wrap(Clob clob) {
return clob instanceof NClob nclob
? wrap( nclob )
: SerializableClobProxy.generateProxy( clob );
}
@Override
public NClob wrap(NClob nclob) {
return SerializableNClobProxy.generateProxy( nclob );
}
@Override
public Blob createBlob(Blob blob) {
return blob;
}
@Override
public Clob createClob(Clob clob) {
return clob;
}
@Override
public NClob createNClob(NClob clob) {
return clob;
}
}

View File

@ -1,219 +0,0 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Clob;
import java.sql.SQLException;
import org.hibernate.Internal;
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
import org.hibernate.type.descriptor.java.DataHelper;
/**
* Manages aspects of proxying {@link Clob}s for non-contextual creation, including proxy creation and
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
*
* @apiNote This class is not intended to be called directly by the application program.
* Instead, use {@link org.hibernate.Session#getLobHelper()}.
*
* @see NClobProxy
* @see BlobProxy
* @see LobCreator
* @see org.hibernate.LobHelper
*
* @author Gavin King
* @author Steve Ebersole
* @author Gail Badner
*/
@Internal
public class ClobProxy implements InvocationHandler {
private static final Class<?>[] PROXY_INTERFACES = new Class[] { Clob.class, ClobImplementer.class };
private final CharacterStream characterStream;
private boolean needsReset;
/**
* Constructor used to build {@link Clob} from string data.
*
* @param string The byte array
* @see #generateProxy(String)
*/
protected ClobProxy(String string) {
this.characterStream = new CharacterStreamImpl( string );
}
/**
* Constructor used to build {@link Clob} from a reader.
*
* @param reader The character reader.
* @param length The length of the reader stream.
* @see #generateProxy(Reader, long)
*/
protected ClobProxy(Reader reader, long length) {
this.characterStream = new CharacterStreamImpl( reader, length );
}
protected long getLength() {
return characterStream.getLength();
}
protected InputStream getAsciiStream() throws SQLException {
return new ReaderInputStream( getCharacterStream() );
}
protected Reader getCharacterStream() throws SQLException {
return getUnderlyingStream().asReader();
}
protected CharacterStream getUnderlyingStream() throws SQLException {
resetIfNeeded();
return characterStream;
}
protected String getSubString(long start, int length) {
final String string = characterStream.asString();
// semi-naive implementation
final int endIndex = Math.min( ( (int) start ) + length, string.length() );
return string.substring( (int) start, endIndex );
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException if any methods other than {@link Clob#length},
* {@link Clob#getAsciiStream}, {@link Clob#getCharacterStream},
* {@link ClobImplementer#getUnderlyingStream}, {@link Clob#getSubString},
* {@link Clob#free}, or toString/equals/hashCode are invoked.
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String methodName = method.getName();
final int argCount = method.getParameterCount();
switch ( methodName ) {
case "length":
if ( argCount == 0 ) {
return getLength();
}
break;
case "getUnderlyingStream":
return getUnderlyingStream(); // Reset stream if needed
case "getCharacterStream":
if ( argCount == 0 ) {
return getCharacterStream();
}
else if ( argCount == 2 ) {
final long start = (Long) args[0];
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > getLength() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + getLength() + "]" );
}
final int length = (Integer) args[1];
if ( length < 0 ) {
// javadoc for getCharacterStream(long,int) specify that the start+length must not exceed the
// total length (this is at odds with the behavior of getSubString(long,int))
throw new SQLException( "Length must be greater than or equal to zero" );
}
return DataHelper.subStream( getCharacterStream(), start-1, length );
}
break;
case "getAsciiStream":
if ( argCount == 0 ) {
return getAsciiStream();
}
break;
case "getSubString":
if ( argCount == 2 ) {
final long start = (Long) args[0];
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > getLength() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + getLength() + "]" );
}
final int length = (Integer) args[1];
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
return getSubString( start-1, length );
}
break;
case "free":
if ( argCount == 0 ) {
characterStream.release();
return null;
}
break;
case "toString":
if ( argCount == 0 ) {
return this.toString();
}
break;
case "equals":
if ( argCount == 1 ) {
return proxy == args[0];
}
break;
case "hashCode":
if ( argCount == 0 ) {
return this.hashCode();
}
break;
}
throw new UnsupportedOperationException( "Clob may not be manipulated from creating session" );
}
protected void resetIfNeeded() throws SQLException {
try {
if ( needsReset ) {
characterStream.asReader().reset();
}
}
catch ( IOException ioe ) {
throw new SQLException( "could not reset reader", ioe );
}
needsReset = true;
}
/**
* Generates a {@link Clob} proxy using the string data.
*
* @param string The data to be wrapped as a {@link Clob}.
*
* @return The generated proxy.
*/
public static Clob generateProxy(String string) {
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( string ) );
}
/**
* Generates a {@link Clob} proxy using a character reader of given length.
*
* @param reader The character reader
* @param length The length of the character reader
*
* @return The generated proxy.
*/
public static Clob generateProxy(Reader reader, long length) {
return (Clob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new ClobProxy( reader, length ) );
}
/**
* Determines the appropriate class loader to which the generated proxy
* should be scoped.
*
* @return The class loader appropriate for proxy construction.
*/
protected static ClassLoader getProxyClassLoader() {
return ClobImplementer.class.getClassLoader();
}
}

View File

@ -28,7 +28,8 @@ public interface LobCreator {
* Wrap the given blob in a serializable wrapper.
*
* @param blob The blob to be wrapped.
* @return The wrapped blob which will be castable to {@link Blob} as well as {@link WrappedBlob}.
* @return The wrapped blob which will be castable to {@link Blob}
* as well as {@link org.hibernate.engine.jdbc.proxy.WrappedBlob}.
*/
Blob wrap(Blob blob);
@ -36,7 +37,8 @@ public interface LobCreator {
* Wrap the given clob in a serializable wrapper.
*
* @param clob The clob to be wrapped.
* @return The wrapped clob which will be castable to {@link Clob} as well as {@link WrappedClob}.
* @return The wrapped clob which will be castable to {@link Clob}
* as well as {@link org.hibernate.engine.jdbc.proxy.WrappedClob}.
*/
Clob wrap(Clob clob);
@ -44,7 +46,8 @@ public interface LobCreator {
* Wrap the given nclob in a serializable wrapper.
*
* @param nclob The nclob to be wrapped.
* @return The wrapped nclob which will be castable to {@link NClob} as well as {@link WrappedNClob}.
* @return The wrapped nclob which will be castable to {@link NClob}
* as well as {@link org.hibernate.engine.jdbc.proxy.WrappedNClob}.
*/
NClob wrap(NClob nclob);
@ -101,7 +104,39 @@ public interface LobCreator {
*/
NClob createNClob(Reader reader, long length);
Blob createBlob(Blob clob);
Clob createClob(Clob clob);
NClob createNClob(NClob clob);
/**
* Return an instance which can actually be written to a JDBC
* {@code PreparedStatement}.
*
* @apiNote This is needed for Oracle
*
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob
*
* @since 7.0
*/
Blob toJdbcBlob(Blob clob);
/**
* Return an instance which can actually be written to a JDBC
* {@code PreparedStatement}.
*
* @apiNote This is needed for Oracle
*
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob
*
* @since 7.0
*/
Clob toJdbcClob(Clob clob);
/**
* Return an instance which can actually be written to a JDBC
* {@code PreparedStatement}.
*
* @apiNote This is needed for Oracle
*
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob
*
* @since 7.0
*/
NClob toJdbcNClob(NClob clob);
}

View File

@ -0,0 +1,66 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc.env.internal;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.proxy.WrappedBlob;
import org.hibernate.engine.jdbc.proxy.WrappedClob;
import org.hibernate.engine.jdbc.proxy.WrappedNClob;
import org.hibernate.engine.jdbc.proxy.SerializableBlobProxy;
import org.hibernate.engine.jdbc.proxy.SerializableClobProxy;
import org.hibernate.engine.jdbc.proxy.SerializableNClobProxy;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.NClob;
/**
* Convenient base class for proxy-based {@link LobCreator} for handling wrapping.
*
* @author Steve Ebersole
*/
public abstract class AbstractLobCreator implements LobCreator {
@Override
public Blob wrap(Blob blob) {
return SerializableBlobProxy.generateProxy( blob );
}
@Override
public Clob wrap(Clob clob) {
return clob instanceof NClob nclob
? wrap( nclob )
: SerializableClobProxy.generateProxy( clob );
}
@Override
public NClob wrap(NClob nclob) {
return SerializableNClobProxy.generateProxy( nclob );
}
@Override
public Blob toJdbcBlob(Blob blob) {
if ( blob instanceof WrappedBlob wrappedBlob ) {
blob = wrappedBlob.getWrappedBlob();
}
return blob;
}
@Override
public Clob toJdbcClob(Clob clob) {
if ( clob instanceof WrappedClob wrappedClob ) {
clob = wrappedClob.getWrappedClob();
}
return clob;
}
@Override
public NClob toJdbcNClob(NClob clob) {
if ( clob instanceof WrappedNClob wrappedNClob ) {
clob = wrappedNClob.getWrappedNClob();
}
return clob;
}
}

View File

@ -13,11 +13,9 @@ import java.sql.NClob;
import java.sql.SQLException;
import org.hibernate.JDBCException;
import org.hibernate.engine.jdbc.AbstractLobCreator;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NClobProxy;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.proxy.NClobProxy;
/**
* {@link LobCreator} which can use {@link Connection#createBlob} and {@link Connection#createClob},
@ -42,7 +40,7 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
protected final LobCreationContext lobCreationContext;
protected final boolean useConnectionToCreateLob;
public BlobAndClobCreator(LobCreationContext lobCreationContext, boolean useConnectionToCreateLob) {
BlobAndClobCreator(LobCreationContext lobCreationContext, boolean useConnectionToCreateLob) {
this.lobCreationContext = lobCreationContext;
this.useConnectionToCreateLob = useConnectionToCreateLob;
}
@ -52,7 +50,7 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
*
* @return The created BLOB reference.
*/
public Blob createBlob() {
Blob createBlob() {
return lobCreationContext.fromContext( CREATE_BLOB_CALLBACK );
}
@ -116,11 +114,11 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
}
@Override
public Blob createBlob(Blob blob) {
public Blob toJdbcBlob(Blob blob) {
try {
return useConnectionToCreateLob
? createBlob( blob.getBytes( 1, (int) blob.length() ) )
: blob;
: super.toJdbcBlob( blob );
}
catch (SQLException e) {
throw new JDBCException( "Could not create JDBC Clob", e );
@ -128,11 +126,11 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
}
@Override
public Clob createClob(Clob clob) {
public Clob toJdbcClob(Clob clob) {
try {
return useConnectionToCreateLob
? createClob( clob.getSubString( 1, (int) clob.length() ) )
: clob;
: super.toJdbcClob( clob );
}
catch (SQLException e) {
throw new JDBCException( "Could not create JDBC Clob", e );
@ -140,11 +138,11 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
}
@Override
public NClob createNClob(NClob clob) {
public NClob toJdbcNClob(NClob clob) {
try {
return useConnectionToCreateLob
? createNClob( clob.getSubString( 1, (int) clob.length() ) )
: clob;
: super.toJdbcNClob( clob );
}
catch (SQLException e) {
throw new JDBCException( "Could not create JDBC Clob", e );

View File

@ -11,7 +11,6 @@ import java.util.Map;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.spi.LobCreatorBuilder;
import static org.hibernate.engine.jdbc.env.internal.LobCreationHelper.NONE;

View File

@ -2,7 +2,12 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.env.internal;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.engine.jdbc.proxy.ClobProxy;
import org.hibernate.engine.jdbc.proxy.NClobProxy;
import java.io.InputStream;
import java.io.Reader;

View File

@ -12,7 +12,6 @@ import java.sql.SQLException;
import org.hibernate.JDBCException;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
/**
* {@linkplain LobCreator} implementation using {@linkplain Connection#createBlob},
@ -28,7 +27,7 @@ public class StandardLobCreator extends BlobAndClobCreator {
*/
public static final LobCreationContext.Callback<NClob> CREATE_NCLOB_CALLBACK = Connection::createNClob;
public StandardLobCreator(LobCreationContext lobCreationContext, boolean useConnectionToCreateLob) {
StandardLobCreator(LobCreationContext lobCreationContext, boolean useConnectionToCreateLob) {
super( lobCreationContext, useConnectionToCreateLob );
}

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.io.IOException;
import java.io.InputStream;
@ -11,6 +11,9 @@ import java.sql.Blob;
import java.sql.SQLException;
import org.hibernate.Internal;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
import org.hibernate.engine.jdbc.internal.StreamBackedBinaryStream;
import org.hibernate.type.descriptor.java.DataHelper;

View File

@ -0,0 +1,193 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc.proxy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.Clob;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.Internal;
import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.internal.util.ReaderInputStream;
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
import org.hibernate.type.descriptor.java.DataHelper;
/**
* Manages aspects of proxying {@link Clob}s for non-contextual creation, including proxy creation and
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
*
* @apiNote This class is not intended to be called directly by the application program.
* Instead, use {@link org.hibernate.Session#getLobHelper()}.
*
* @see NClobProxy
* @see BlobProxy
* @see LobCreator
* @see org.hibernate.LobHelper
*
* @author Gavin King
* @author Steve Ebersole
* @author Gail Badner
*/
@Internal
public class ClobProxy implements Clob, ClobImplementer {
private final CharacterStream characterStream;
private boolean needsReset;
/**
* Constructor used to build {@link Clob} from string data.
*
* @param string The byte array
* @see #generateProxy(String)
*/
protected ClobProxy(String string) {
this.characterStream = new CharacterStreamImpl( string );
}
/**
* Constructor used to build {@link Clob} from a reader.
*
* @param reader The character reader.
* @param length The length of the reader stream.
* @see #generateProxy(Reader, long)
*/
protected ClobProxy(Reader reader, long length) {
this.characterStream = new CharacterStreamImpl( reader, length );
}
@Override
public long length() {
return characterStream.getLength();
}
@Override
public InputStream getAsciiStream() throws SQLException {
return new ReaderInputStream( getCharacterStream() );
}
@Override
public Reader getCharacterStream() throws SQLException {
return getUnderlyingStream().asReader();
}
@Override
public CharacterStream getUnderlyingStream() {
resetIfNeeded();
return characterStream;
}
@Override
public long position(String searchstr, long start) throws SQLException {
return characterStream.asString().indexOf( searchstr, (int) start + 1 );
}
@Override
public long position(Clob searchstr, long start) throws SQLException {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
@Override
public int setString(long pos, String str) throws SQLException {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
@Override
public int setString(long pos, String str, int offset, int len) throws SQLException {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
@Override
public OutputStream setAsciiStream(long pos) {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
@Override
public Writer setCharacterStream(long pos) {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
@Override
public void truncate(long len) throws SQLException {
throw new UnsupportedOperationException("Clob may not be manipulated from creating session");
}
public String getSubString(long start, int length) throws SQLException {
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > length() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + length() + "]" );
}
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
final String string = characterStream.asString();
final long endIndex = Math.min( start + length - 1, string.length() );
return string.substring( (int) start - 1, (int) endIndex );
}
@Override
public Reader getCharacterStream(long start, long length) throws SQLException {
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > length() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + length() + "]" );
}
if ( length < 0 ) {
// javadoc for getCharacterStream(long,int) specify that the start+length must not exceed the
// total length (this is at odds with the behavior of getSubString(long,int))
throw new SQLException( "Length must be greater than or equal to zero" );
}
return DataHelper.subStream( getCharacterStream(), start-1, (int) length );
}
@Override
public void free() throws SQLException {
characterStream.release();
}
protected void resetIfNeeded() {
try {
if ( needsReset ) {
characterStream.asReader().reset();
}
}
catch ( IOException ioe ) {
throw new HibernateException( "could not reset reader", ioe );
}
needsReset = true;
}
/**
* Generates a {@link Clob} proxy using the string data.
*
* @param string The data to be wrapped as a {@link Clob}.
*
* @return The generated proxy.
*/
public static Clob generateProxy(String string) {
return new ClobProxy( string );
}
/**
* Generates a {@link Clob} proxy using a character reader of given length.
*
* @param reader The character reader
* @param length The length of the character reader
*
* @return The generated proxy.
*/
public static Clob generateProxy(Reader reader, long length) {
return new ClobProxy( reader, length );
}
}

View File

@ -2,20 +2,18 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import org.hibernate.Internal;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NClobImplementer;
import java.io.Reader;
import java.lang.reflect.Proxy;
import java.sql.NClob;
/**
* Manages aspects of proxying {@link NClob}s for non-contextual creation, including proxy creation and
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
* <p>
* Generated proxies are typed as {@link java.sql.Clob} ({@code NClob} extends {@code Clob})and in JDK 1.6+
* environments, they are also typed to {@code NClob}.
*
* @apiNote This class is not intended to be called directly by the application program.
* Instead, use {@link org.hibernate.Session#getLobHelper()}.
@ -28,11 +26,7 @@ import java.sql.NClob;
* @author Steve Ebersole
*/
@Internal
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 class NClobProxy extends ClobProxy implements NClob, NClobImplementer {
protected NClobProxy(String string) {
super( string );
@ -50,7 +44,7 @@ public class NClobProxy extends ClobProxy {
* @return The generated proxy.
*/
public static NClob generateProxy(String string) {
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new NClobProxy( string ) );
return new NClobProxy( string );
}
/**
@ -62,7 +56,7 @@ public class NClobProxy extends ClobProxy {
* @return The generated proxy.
*/
public static NClob generateProxy(Reader reader, long length) {
return (NClob) Proxy.newProxyInstance( getProxyClassLoader(), PROXY_INTERFACES, new NClobProxy( reader, length ) );
return new NClobProxy( reader, length );
}
/**

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
@ -12,6 +12,7 @@ import java.lang.reflect.Proxy;
import java.sql.Blob;
import org.hibernate.HibernateException;
import org.hibernate.Internal;
/**
* Manages aspects of proxying {@link Blob}s to add serializability.
@ -20,6 +21,7 @@ import org.hibernate.HibernateException;
* @author Steve Ebersole
* @author Gail Badner
*/
@Internal
public class SerializableBlobProxy implements InvocationHandler, Serializable {
private static final Class<?>[] PROXY_INTERFACES = new Class[] { Blob.class, WrappedBlob.class, Serializable.class };

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
@ -12,6 +12,7 @@ import java.lang.reflect.Proxy;
import java.sql.Clob;
import org.hibernate.HibernateException;
import org.hibernate.Internal;
/**
* Manages aspects of proxying {@link Clob}s to add serializability.
@ -20,6 +21,7 @@ import org.hibernate.HibernateException;
* @author Steve Ebersole
* @author Gail Badner
*/
@Internal
public class SerializableClobProxy implements InvocationHandler, Serializable {
private static final Class<?>[] PROXY_INTERFACES = new Class[] { Clob.class, WrappedClob.class, Serializable.class };

View File

@ -2,7 +2,9 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import org.hibernate.Internal;
import java.lang.reflect.Proxy;
import java.sql.Clob;
@ -13,6 +15,7 @@ import java.sql.NClob;
*
* @author Steve Ebersole
*/
@Internal
public class SerializableNClobProxy extends SerializableClobProxy {
private static final Class<?>[] PROXY_INTERFACES = new Class[] { NClob.class, WrappedNClob.class };

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.sql.Blob;

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.sql.Clob;

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.engine.jdbc.proxy;
import java.sql.NClob;

View File

@ -57,7 +57,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLaziness
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.spi.ActionQueue;
import org.hibernate.engine.spi.ActionQueue.TransactionCompletionProcesses;

View File

@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc;
package org.hibernate.internal.util;
import java.io.IOException;
import java.io.InputStream;

View File

@ -15,10 +15,9 @@ import org.hibernate.SharedSessionContract;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.internal.StreamBackedBinaryStream;
import org.hibernate.engine.jdbc.WrappedBlob;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -113,11 +112,7 @@ public class BlobJavaType extends AbstractClassJavaType<Blob> {
try {
if ( Blob.class.isAssignableFrom( type ) ) {
Blob blob = value;
if ( blob instanceof WrappedBlob wrappedBlob ) {
blob = wrappedBlob.getWrappedBlob();
}
return (X) options.getLobCreator().createBlob( blob );
return (X) options.getLobCreator().toJdbcBlob( value );
}
else if ( byte[].class.isAssignableFrom( type )) {
if (value instanceof BlobImplementer blobImplementer) {

View File

@ -15,9 +15,8 @@ import org.hibernate.SharedSessionContract;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.engine.jdbc.ClobProxy;
import org.hibernate.engine.jdbc.proxy.ClobProxy;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.WrappedClob;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -85,11 +84,7 @@ public class ClobJavaType extends AbstractClassJavaType<Clob> {
try {
if ( Clob.class.isAssignableFrom( type ) ) {
Clob clob = value;
if ( clob instanceof WrappedClob wrappedClob ) {
clob = wrappedClob.getWrappedClob();
}
return (X) options.getLobCreator().createClob( clob );
return (X) options.getLobCreator().toJdbcClob( value );
}
else if ( String.class.isAssignableFrom( type ) ) {
if (value instanceof ClobImplementer clobImplementer) {

View File

@ -139,7 +139,7 @@ public final class DataHelper {
*
* @return The content portion as a reader
*/
public static Object subStream(Reader characterStream, long start, int length) {
public static Reader subStream(Reader characterStream, long start, int length) {
return new StringReader( extractString( characterStream, start, length ) );
}

View File

@ -14,8 +14,7 @@ import org.hibernate.SharedSessionContract;
import org.hibernate.engine.jdbc.CharacterStream;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NClobImplementer;
import org.hibernate.engine.jdbc.NClobProxy;
import org.hibernate.engine.jdbc.WrappedNClob;
import org.hibernate.engine.jdbc.proxy.NClobProxy;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
@ -94,11 +93,7 @@ public class NClobJavaType extends AbstractClassJavaType<NClob> {
try {
if ( NClob.class.isAssignableFrom( type ) ) {
NClob clob = value;
if ( clob instanceof WrappedNClob wrappedNClob ) {
clob = wrappedNClob.getWrappedNClob();
}
return (X) options.getLobCreator().createNClob( clob );
return (X) options.getLobCreator().toJdbcNClob( value );
}
else if ( String.class.isAssignableFrom( type ) ) {
if (value instanceof NClobImplementer clobImplementer) {

View File

@ -4,6 +4,7 @@
*/
package org.hibernate.engine.jdbc;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.testing.orm.junit.JiraKey;
import org.junit.jupiter.api.Test;

View File

@ -10,7 +10,7 @@ import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.ReaderInputStream;
import org.hibernate.internal.util.ReaderInputStream;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;

View File

@ -9,7 +9,7 @@ import java.io.StringReader;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.ReaderInputStream;
import org.hibernate.internal.util.ReaderInputStream;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.orm.junit.JiraKey;

View File

@ -8,7 +8,7 @@ import java.io.StringReader;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.ReaderInputStream;
import org.hibernate.internal.util.ReaderInputStream;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
import org.hibernate.query.named.NamedResultSetMappingMemento;

View File

@ -33,9 +33,9 @@ import org.hibernate.engine.jdbc.ClobImplementer;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NClobImplementer;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.WrappedBlob;
import org.hibernate.engine.jdbc.WrappedClob;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.jdbc.proxy.WrappedBlob;
import org.hibernate.engine.jdbc.proxy.WrappedClob;
import org.hibernate.engine.jdbc.env.internal.BlobAndClobCreator;
import org.hibernate.engine.jdbc.env.internal.LobCreationHelper;
import org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl;

View File

@ -9,7 +9,7 @@ import java.sql.Blob;
import java.sql.SQLException;
import org.hibernate.LobHelper;
import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;

View File

@ -14,7 +14,7 @@ import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import org.hibernate.Session;
import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;

View File

@ -14,7 +14,7 @@ import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import org.hibernate.Session;
import org.hibernate.engine.jdbc.ClobProxy;
import org.hibernate.engine.jdbc.proxy.ClobProxy;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;

View File

@ -11,7 +11,7 @@ import jakarta.persistence.Lob;
import org.hibernate.annotations.Nationalized;
import org.hibernate.dialect.SybaseASEDialect;
import org.hibernate.engine.jdbc.NClobProxy;
import org.hibernate.engine.jdbc.proxy.NClobProxy;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;

View File

@ -11,7 +11,7 @@ import java.util.TimeZone;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;

View File

@ -15,7 +15,7 @@ import java.sql.Blob;
import java.sql.SQLException;
import org.hibernate.engine.jdbc.BlobImplementer;
import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.engine.jdbc.proxy.BlobProxy;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.type.descriptor.java.BlobJavaType;
import org.hibernate.type.descriptor.java.DataHelper;

View File

@ -16,7 +16,7 @@ import java.util.TimeZone;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.ValueBinder;

View File

@ -13,7 +13,7 @@ import java.time.ZoneOffset;
import java.util.TimeZone;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;

View File

@ -13,7 +13,7 @@ import java.util.TimeZone;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.ValueBinder;