HHH-7698 - In efficient LOB creations backed by streams
This commit is contained in:
parent
e5d3b2b34c
commit
d118c24776
|
@ -31,16 +31,12 @@ import java.sql.Clob;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractLobCreator implements LobCreator {
|
public abstract class AbstractLobCreator implements LobCreator {
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Blob wrap(Blob blob) {
|
public Blob wrap(Blob blob) {
|
||||||
return SerializableBlobProxy.generateProxy( blob );
|
return SerializableBlobProxy.generateProxy( blob );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Clob wrap(Clob clob) {
|
public Clob wrap(Clob clob) {
|
||||||
if ( SerializableNClobProxy.isNClob( clob ) ) {
|
if ( SerializableNClobProxy.isNClob( clob ) ) {
|
||||||
return SerializableNClobProxy.generateProxy( clob );
|
return SerializableNClobProxy.generateProxy( clob );
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor;
|
package org.hibernate.engine.jdbc;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,5 +50,10 @@ public interface BinaryStream {
|
||||||
*
|
*
|
||||||
* @return The input stream length
|
* @return The input stream length
|
||||||
*/
|
*/
|
||||||
public int getLength();
|
public long getLength();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any underlying resources.
|
||||||
|
*/
|
||||||
|
public void release();
|
||||||
}
|
}
|
|
@ -23,11 +23,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc;
|
package org.hibernate.engine.jdbc;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker interface for non-contextually created {@link java.sql.Blob} instances..
|
* Marker interface for non-contextually created {@link java.sql.Blob} instances..
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface BlobImplementer {
|
public interface BlobImplementer {
|
||||||
|
/**
|
||||||
|
* Gets access to the data underlying this BLOB.
|
||||||
|
*
|
||||||
|
* @return Access to the underlying data.
|
||||||
|
*/
|
||||||
|
public BinaryStream getUnderlyingStream();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
@ -30,12 +31,12 @@ import java.lang.reflect.Proxy;
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.java.BinaryStreamImpl;
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.type.descriptor.java.DataHelper;
|
import org.hibernate.type.descriptor.java.DataHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages aspects of proxying {@link Blob Blobs} for non-contextual creation, including proxy creation and
|
* Manages aspects of proxying {@link Blob} references for non-contextual creation, including proxy creation and
|
||||||
* handling proxy invocations.
|
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -44,8 +45,7 @@ import org.hibernate.type.descriptor.java.DataHelper;
|
||||||
public class BlobProxy implements InvocationHandler {
|
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 InputStream stream;
|
private BinaryStream binaryStream;
|
||||||
private long length;
|
|
||||||
private boolean needsReset = false;
|
private boolean needsReset = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +55,7 @@ public class BlobProxy implements InvocationHandler {
|
||||||
* @see #generateProxy(byte[])
|
* @see #generateProxy(byte[])
|
||||||
*/
|
*/
|
||||||
private BlobProxy(byte[] bytes) {
|
private BlobProxy(byte[] bytes) {
|
||||||
this.stream = new BinaryStreamImpl( bytes );
|
binaryStream = new BinaryStreamImpl( bytes );
|
||||||
this.length = bytes.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,17 +66,17 @@ public class BlobProxy implements InvocationHandler {
|
||||||
* @see #generateProxy(java.io.InputStream, long)
|
* @see #generateProxy(java.io.InputStream, long)
|
||||||
*/
|
*/
|
||||||
private BlobProxy(InputStream stream, long length) {
|
private BlobProxy(InputStream stream, long length) {
|
||||||
this.stream = stream;
|
this.binaryStream = new StreamBackedBinaryStream( stream, length );
|
||||||
this.length = length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getLength() {
|
private long getLength() {
|
||||||
return length;
|
return binaryStream.getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream getStream() throws SQLException {
|
private InputStream getStream() throws SQLException {
|
||||||
|
InputStream stream = binaryStream.getInputStream();
|
||||||
try {
|
try {
|
||||||
if (needsReset) {
|
if ( needsReset ) {
|
||||||
stream.reset();
|
stream.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +93,7 @@ public class BlobProxy implements InvocationHandler {
|
||||||
* @throws UnsupportedOperationException if any methods other than {@link Blob#length()}
|
* @throws UnsupportedOperationException if any methods other than {@link Blob#length()}
|
||||||
* or {@link Blob#getBinaryStream} are invoked.
|
* or {@link Blob#getBinaryStream} are invoked.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
@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 {
|
||||||
final String methodName = method.getName();
|
final String methodName = method.getName();
|
||||||
|
@ -102,6 +102,9 @@ public class BlobProxy implements InvocationHandler {
|
||||||
if ( "length".equals( methodName ) && argCount == 0 ) {
|
if ( "length".equals( methodName ) && argCount == 0 ) {
|
||||||
return Long.valueOf( getLength() );
|
return Long.valueOf( getLength() );
|
||||||
}
|
}
|
||||||
|
if ( "getUnderlyingStream".equals( methodName ) ) {
|
||||||
|
return binaryStream;
|
||||||
|
}
|
||||||
if ( "getBinaryStream".equals( methodName ) ) {
|
if ( "getBinaryStream".equals( methodName ) ) {
|
||||||
if ( argCount == 0 ) {
|
if ( argCount == 0 ) {
|
||||||
return getStream();
|
return getStream();
|
||||||
|
@ -137,7 +140,7 @@ public class BlobProxy implements InvocationHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( "free".equals( methodName ) && argCount == 0 ) {
|
if ( "free".equals( methodName ) && argCount == 0 ) {
|
||||||
stream.close();
|
binaryStream.release();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ( "toString".equals( methodName ) && argCount == 0 ) {
|
if ( "toString".equals( methodName ) && argCount == 0 ) {
|
||||||
|
@ -197,4 +200,43 @@ public class BlobProxy implements InvocationHandler {
|
||||||
}
|
}
|
||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class StreamBackedBinaryStream implements BinaryStream {
|
||||||
|
private final InputStream stream;
|
||||||
|
private final long length;
|
||||||
|
|
||||||
|
private byte[] bytes;
|
||||||
|
|
||||||
|
private StreamBackedBinaryStream(InputStream stream, long length) {
|
||||||
|
this.stream = stream;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() {
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes() {
|
||||||
|
if ( bytes == null ) {
|
||||||
|
bytes = DataHelper.extractBytes( stream );
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() {
|
||||||
|
return (int) length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor;
|
package org.hibernate.engine.jdbc;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,17 +34,28 @@ import java.io.Reader;
|
||||||
*/
|
*/
|
||||||
public interface CharacterStream {
|
public interface CharacterStream {
|
||||||
/**
|
/**
|
||||||
* Retrieve the reader.
|
* Provides access to the underlying data as a Reader.
|
||||||
*
|
*
|
||||||
* @return The reader.
|
* @return The reader.
|
||||||
*/
|
*/
|
||||||
public Reader getReader();
|
public Reader asReader();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the number of characters. JDBC 3 and earlier defined the length in terms of int type rather than
|
* Provides access to the underlying data as a String.
|
||||||
* long type :(
|
*
|
||||||
|
* @return The underlying String data
|
||||||
|
*/
|
||||||
|
public String asString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the number of characters.
|
||||||
*
|
*
|
||||||
* @return The number of characters.
|
* @return The number of characters.
|
||||||
*/
|
*/
|
||||||
public int getLength();
|
public long getLength();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any underlying resources.
|
||||||
|
*/
|
||||||
|
public void release();
|
||||||
}
|
}
|
|
@ -23,11 +23,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc;
|
package org.hibernate.engine.jdbc;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker interface for non-contextually created {@link java.sql.Clob} instances..
|
* Marker interface for non-contextually created {@link java.sql.Clob} instances..
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface ClobImplementer {
|
public interface ClobImplementer {
|
||||||
|
/**
|
||||||
|
* Gets access to the data underlying this CLOB.
|
||||||
|
*
|
||||||
|
* @return Access to the underlying data.
|
||||||
|
*/
|
||||||
|
public CharacterStream getUnderlyingStream();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,12 @@ import java.lang.reflect.Proxy;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||||
import org.hibernate.type.descriptor.java.DataHelper;
|
import org.hibernate.type.descriptor.java.DataHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages aspects of proxying {@link Clob Clobs} for non-contextual creation, including proxy creation and
|
* Manages aspects of proxying {@link Clob Clobs} for non-contextual creation, including proxy creation and
|
||||||
* handling proxy invocations.
|
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -46,12 +47,9 @@ import org.hibernate.type.descriptor.java.DataHelper;
|
||||||
public class ClobProxy implements InvocationHandler {
|
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 String string;
|
private final CharacterStream characterStream;
|
||||||
private Reader reader;
|
|
||||||
private long length;
|
|
||||||
private boolean needsReset = false;
|
private boolean needsReset = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used to build {@link Clob} from string data.
|
* Constructor used to build {@link Clob} from string data.
|
||||||
*
|
*
|
||||||
|
@ -59,9 +57,7 @@ public class ClobProxy implements InvocationHandler {
|
||||||
* @see #generateProxy(String)
|
* @see #generateProxy(String)
|
||||||
*/
|
*/
|
||||||
protected ClobProxy(String string) {
|
protected ClobProxy(String string) {
|
||||||
this.string = string;
|
this.characterStream = new CharacterStreamImpl( string );
|
||||||
reader = new StringReader(string);
|
|
||||||
length = string.length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,28 +68,25 @@ public class ClobProxy implements InvocationHandler {
|
||||||
* @see #generateProxy(java.io.Reader, long)
|
* @see #generateProxy(java.io.Reader, long)
|
||||||
*/
|
*/
|
||||||
protected ClobProxy(Reader reader, long length) {
|
protected ClobProxy(Reader reader, long length) {
|
||||||
this.reader = reader;
|
this.characterStream = new CharacterStreamImpl( reader, length );
|
||||||
this.length = length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long getLength() {
|
protected long getLength() {
|
||||||
return length;
|
return characterStream.getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InputStream getAsciiStream() throws SQLException {
|
protected InputStream getAsciiStream() throws SQLException {
|
||||||
resetIfNeeded();
|
resetIfNeeded();
|
||||||
return new ReaderInputStream( reader );
|
return new ReaderInputStream( characterStream.asReader() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Reader getCharacterStream() throws SQLException {
|
protected Reader getCharacterStream() throws SQLException {
|
||||||
resetIfNeeded();
|
resetIfNeeded();
|
||||||
return reader;
|
return characterStream.asReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getSubString(long start, int length) {
|
protected String getSubString(long start, int length) {
|
||||||
if ( string == null ) {
|
final String string = characterStream.asString();
|
||||||
throw new UnsupportedOperationException( "Clob was not created from string; cannot substring" );
|
|
||||||
}
|
|
||||||
// semi-naive implementation
|
// semi-naive implementation
|
||||||
int endIndex = Math.min( ((int)start)+length, string.length() );
|
int endIndex = Math.min( ((int)start)+length, string.length() );
|
||||||
return string.substring( (int)start, endIndex );
|
return string.substring( (int)start, endIndex );
|
||||||
|
@ -105,6 +98,7 @@ public class ClobProxy implements InvocationHandler {
|
||||||
* @throws UnsupportedOperationException if any methods other than {@link Clob#length()},
|
* @throws UnsupportedOperationException if any methods other than {@link Clob#length()},
|
||||||
* {@link Clob#getAsciiStream()}, or {@link Clob#getCharacterStream()} are invoked.
|
* {@link Clob#getAsciiStream()}, or {@link Clob#getCharacterStream()} are invoked.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
@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 {
|
||||||
final String methodName = method.getName();
|
final String methodName = method.getName();
|
||||||
|
@ -113,6 +107,9 @@ public class ClobProxy implements InvocationHandler {
|
||||||
if ( "length".equals( methodName ) && argCount == 0 ) {
|
if ( "length".equals( methodName ) && argCount == 0 ) {
|
||||||
return Long.valueOf( getLength() );
|
return Long.valueOf( getLength() );
|
||||||
}
|
}
|
||||||
|
if ( "getUnderlyingStream".equals( methodName ) ) {
|
||||||
|
return characterStream;
|
||||||
|
}
|
||||||
if ( "getAsciiStream".equals( methodName ) && argCount == 0 ) {
|
if ( "getAsciiStream".equals( methodName ) && argCount == 0 ) {
|
||||||
return getAsciiStream();
|
return getAsciiStream();
|
||||||
}
|
}
|
||||||
|
@ -152,7 +149,7 @@ public class ClobProxy implements InvocationHandler {
|
||||||
return getSubString( start-1, length );
|
return getSubString( start-1, length );
|
||||||
}
|
}
|
||||||
if ( "free".equals( methodName ) && argCount == 0 ) {
|
if ( "free".equals( methodName ) && argCount == 0 ) {
|
||||||
reader.close();
|
characterStream.release();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ( "toString".equals( methodName ) && argCount == 0 ) {
|
if ( "toString".equals( methodName ) && argCount == 0 ) {
|
||||||
|
@ -171,7 +168,7 @@ public class ClobProxy implements InvocationHandler {
|
||||||
protected void resetIfNeeded() throws SQLException {
|
protected void resetIfNeeded() throws SQLException {
|
||||||
try {
|
try {
|
||||||
if ( needsReset ) {
|
if ( needsReset ) {
|
||||||
reader.reset();
|
characterStream.asReader().reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( IOException ioe ) {
|
catch ( IOException ioe ) {
|
||||||
|
|
|
@ -59,9 +59,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
return lobCreationContext.execute( CREATE_BLOB_CALLBACK );
|
return lobCreationContext.execute( CREATE_BLOB_CALLBACK );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Blob createBlob(byte[] bytes) {
|
public Blob createBlob(byte[] bytes) {
|
||||||
try {
|
try {
|
||||||
Blob blob = createBlob();
|
Blob blob = createBlob();
|
||||||
|
@ -73,25 +71,11 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Blob createBlob(InputStream inputStream, long length) {
|
public Blob createBlob(InputStream inputStream, long length) {
|
||||||
try {
|
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
|
||||||
Blob blob = createBlob();
|
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
|
||||||
OutputStream byteStream = blob.setBinaryStream( 1 );
|
return NonContextualLobCreator.INSTANCE.createBlob( inputStream, length );
|
||||||
StreamUtils.copy( inputStream, byteStream );
|
|
||||||
byteStream.flush();
|
|
||||||
byteStream.close();
|
|
||||||
// todo : validate length written versus length given?
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
catch ( SQLException e ) {
|
|
||||||
throw new JDBCException( "Unable to prepare BLOB binary stream for writing",e );
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
throw new HibernateException( "Unable to write stream contents to BLOB", e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,9 +87,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
return lobCreationContext.execute( CREATE_CLOB_CALLBACK );
|
return lobCreationContext.execute( CREATE_CLOB_CALLBACK );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Clob createClob(String string) {
|
public Clob createClob(String string) {
|
||||||
try {
|
try {
|
||||||
Clob clob = createClob();
|
Clob clob = createClob();
|
||||||
|
@ -117,24 +99,11 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Clob createClob(Reader reader, long length) {
|
public Clob createClob(Reader reader, long length) {
|
||||||
try {
|
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
|
||||||
Clob clob = createClob();
|
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
|
||||||
Writer writer = clob.setCharacterStream( 1 );
|
return NonContextualLobCreator.INSTANCE.createClob( reader, length );
|
||||||
StreamUtils.copy( reader, writer );
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
return clob;
|
|
||||||
}
|
|
||||||
catch ( SQLException e ) {
|
|
||||||
throw new JDBCException( "Unable to prepare CLOB stream for writing", e );
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
throw new HibernateException( "Unable to write CLOB stream content", e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,9 +115,7 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
return lobCreationContext.execute( CREATE_NCLOB_CALLBACK );
|
return lobCreationContext.execute( CREATE_NCLOB_CALLBACK );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public NClob createNClob(String string) {
|
public NClob createNClob(String string) {
|
||||||
try {
|
try {
|
||||||
NClob nclob = createNClob();
|
NClob nclob = createNClob();
|
||||||
|
@ -160,24 +127,11 @@ public class ContextualLobCreator extends AbstractLobCreator implements LobCreat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public NClob createNClob(Reader reader, long length) {
|
public NClob createNClob(Reader reader, long length) {
|
||||||
try {
|
// IMPL NOTE : it is inefficient to use JDBC LOB locator creation to create a LOB
|
||||||
NClob nclob = createNClob();
|
// backed by a given stream. So just wrap the stream (which is what the NonContextualLobCreator does).
|
||||||
Writer writer = nclob.setCharacterStream( 1 );
|
return NonContextualLobCreator.INSTANCE.createNClob( reader, length );
|
||||||
StreamUtils.copy( reader, writer );
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
return nclob;
|
|
||||||
}
|
|
||||||
catch ( SQLException e ) {
|
|
||||||
throw new JDBCException( "Unable to prepare NCLOB stream for writing", e );
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
throw new HibernateException( "Unable to write NCLOB stream content", e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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>() {
|
||||||
|
|
|
@ -31,8 +31,6 @@ import java.sql.NClob;
|
||||||
/**
|
/**
|
||||||
* Contract for creating various LOB references.
|
* Contract for creating various LOB references.
|
||||||
*
|
*
|
||||||
* @todo LobCreator really needs to be an api since we expose it to users.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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.Reader;
|
import java.io.Reader;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
|
@ -29,10 +30,10 @@ import java.sql.NClob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages aspects of proxying java.sql.NClobs for non-contextual creation, including proxy creation and
|
* Manages aspects of proxying java.sql.NClobs for non-contextual creation, including proxy creation and
|
||||||
* handling proxy invocations.
|
* handling proxy invocations. We use proxies here solely to avoid JDBC version incompatibilities.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Generated proxies are typed as {@link java.sql.Clob} (java.sql.NClob extends {@link java.sql.Clob}) and in JDK 1.6 environments, they
|
* Generated proxies are typed as {@link java.sql.Clob} (java.sql.NClob extends {@link java.sql.Clob})
|
||||||
* are also typed to java.sql.NClob
|
* and in JDK 1.6+ environments, they are also typed to java.sql.NClob
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
|
@ -41,44 +42,32 @@ public class NonContextualLobCreator extends AbstractLobCreator implements LobCr
|
||||||
private NonContextualLobCreator() {
|
private NonContextualLobCreator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Blob createBlob(byte[] bytes) {
|
public Blob createBlob(byte[] bytes) {
|
||||||
return BlobProxy.generateProxy( bytes );
|
return BlobProxy.generateProxy( bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Blob createBlob(InputStream stream, long length) {
|
public Blob createBlob(InputStream stream, long length) {
|
||||||
return BlobProxy.generateProxy( stream, length );
|
return BlobProxy.generateProxy( stream, length );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Clob createClob(String string) {
|
public Clob createClob(String string) {
|
||||||
return ClobProxy.generateProxy( string );
|
return ClobProxy.generateProxy( string );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Clob createClob(Reader reader, long length) {
|
public Clob createClob(Reader reader, long length) {
|
||||||
return ClobProxy.generateProxy( reader, length );
|
return ClobProxy.generateProxy( reader, length );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public NClob createNClob(String string) {
|
public NClob createNClob(String string) {
|
||||||
return NClobProxy.generateProxy( string );
|
return NClobProxy.generateProxy( string );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public NClob createNClob(Reader reader, long length) {
|
public NClob createNClob(Reader reader, long length) {
|
||||||
return NClobProxy.generateProxy( reader, length );
|
return NClobProxy.generateProxy( 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, 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
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc;
|
package org.hibernate.engine.jdbc;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -42,5 +41,4 @@ public class ReaderInputStream extends InputStream {
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
return reader.read();
|
return reader.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
@ -62,9 +63,7 @@ public class SerializableBlobProxy implements InvocationHandler, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ( "getWrappedBlob".equals( method.getName() ) ) {
|
if ( "getWrappedBlob".equals( method.getName() ) ) {
|
||||||
return getWrappedBlob();
|
return getWrappedBlob();
|
||||||
|
|
|
@ -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.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
@ -62,9 +63,7 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ( "getWrappedClob".equals( method.getName() ) ) {
|
if ( "getWrappedClob".equals( method.getName() ) ) {
|
||||||
return getWrappedClob();
|
return getWrappedClob();
|
||||||
|
|
|
@ -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.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
|
|
||||||
|
|
|
@ -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.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
|
@ -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.Blob;
|
import java.sql.Blob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.Clob;
|
import java.sql.Clob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,12 +21,13 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.engine.jdbc.internal;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link BinaryStream}
|
* Implementation of {@link BinaryStream}
|
||||||
|
@ -50,7 +51,16 @@ public class BinaryStreamImpl extends ByteArrayInputStream implements BinaryStre
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLength() {
|
public long getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -21,12 +21,15 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.descriptor.java;
|
package org.hibernate.engine.jdbc.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
|
import org.hibernate.type.descriptor.java.DataHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link CharacterStream}
|
* Implementation of {@link CharacterStream}
|
||||||
|
@ -34,19 +37,51 @@ import org.hibernate.type.descriptor.CharacterStream;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CharacterStreamImpl implements CharacterStream {
|
public class CharacterStreamImpl implements CharacterStream {
|
||||||
private final StringReader reader;
|
private final long length;
|
||||||
private final int length;
|
|
||||||
|
private Reader reader;
|
||||||
|
private String string;
|
||||||
|
|
||||||
public CharacterStreamImpl(String chars) {
|
public CharacterStreamImpl(String chars) {
|
||||||
reader = new StringReader( chars );
|
this.string = chars;
|
||||||
length = chars.length();
|
this.length = chars.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reader getReader() {
|
public CharacterStreamImpl(Reader reader, long length) {
|
||||||
|
this.reader = reader;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader asReader() {
|
||||||
|
if ( reader == null ) {
|
||||||
|
reader = new StringReader( string );
|
||||||
|
}
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLength() {
|
@Override
|
||||||
|
public String asString() {
|
||||||
|
if ( string == null ) {
|
||||||
|
string = DataHelper.extractString( reader );
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
if ( reader == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -31,9 +31,11 @@ import java.sql.SQLException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.jdbc.BlobImplementer;
|
||||||
import org.hibernate.engine.jdbc.BlobProxy;
|
import org.hibernate.engine.jdbc.BlobProxy;
|
||||||
import org.hibernate.engine.jdbc.WrappedBlob;
|
import org.hibernate.engine.jdbc.WrappedBlob;
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,16 +119,33 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor<Blob> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( BinaryStream.class.isAssignableFrom( type ) ) {
|
if ( BinaryStream.class.isAssignableFrom( type ) ) {
|
||||||
|
if ( BlobImplementer.class.isInstance( value ) ) {
|
||||||
|
// if the incoming Blob is a wrapper, just pass along its BinaryStream
|
||||||
|
return (X) ( (BlobImplementer) value ).getUnderlyingStream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise we need to build a BinaryStream...
|
||||||
return (X) new BinaryStreamImpl( DataHelper.extractBytes( value.getBinaryStream() ) );
|
return (X) new BinaryStreamImpl( DataHelper.extractBytes( value.getBinaryStream() ) );
|
||||||
} else if ( byte[].class.isAssignableFrom( type )) {
|
}
|
||||||
|
}
|
||||||
|
else if ( byte[].class.isAssignableFrom( type )) {
|
||||||
|
if ( BlobImplementer.class.isInstance( value ) ) {
|
||||||
|
// if the incoming Blob is a wrapper, just grab the bytes from its BinaryStream
|
||||||
|
return (X) ( (BlobImplementer) value ).getUnderlyingStream().getBytes();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise extract the bytes from the stream manually
|
||||||
return (X) DataHelper.extractBytes( value.getBinaryStream() );
|
return (X) DataHelper.extractBytes( value.getBinaryStream() );
|
||||||
} else if (Blob.class.isAssignableFrom( type )) {
|
}
|
||||||
|
}
|
||||||
|
else if (Blob.class.isAssignableFrom( type )) {
|
||||||
final Blob blob = WrappedBlob.class.isInstance( value )
|
final Blob blob = WrappedBlob.class.isInstance( value )
|
||||||
? ( (WrappedBlob) value ).getWrappedBlob()
|
? ( (WrappedBlob) value ).getWrappedBlob()
|
||||||
: value;
|
: value;
|
||||||
return (X) blob;
|
return (X) blob;
|
||||||
}
|
}
|
||||||
} catch ( SQLException e ) {
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
throw new HibernateException( "Unable to access blob stream", e );
|
throw new HibernateException( "Unable to access blob stream", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +161,11 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor<Blob> {
|
||||||
// org.hibernate.type.descriptor.sql.BlobTypeDescriptor
|
// org.hibernate.type.descriptor.sql.BlobTypeDescriptor
|
||||||
if ( Blob.class.isAssignableFrom( value.getClass() ) ) {
|
if ( Blob.class.isAssignableFrom( value.getClass() ) ) {
|
||||||
return options.getLobCreator().wrap( (Blob) value );
|
return options.getLobCreator().wrap( (Blob) value );
|
||||||
} else if ( byte[].class.isAssignableFrom( value.getClass() ) ) {
|
}
|
||||||
|
else if ( byte[].class.isAssignableFrom( value.getClass() ) ) {
|
||||||
return options.getLobCreator().createBlob( ( byte[] ) value);
|
return options.getLobCreator().createBlob( ( byte[] ) value);
|
||||||
} else if ( InputStream.class.isAssignableFrom( value.getClass() ) ) {
|
}
|
||||||
|
else if ( InputStream.class.isAssignableFrom( value.getClass() ) ) {
|
||||||
InputStream inputStream = ( InputStream ) value;
|
InputStream inputStream = ( InputStream ) value;
|
||||||
try {
|
try {
|
||||||
return options.getLobCreator().createBlob( inputStream, inputStream.available() );
|
return options.getLobCreator().createBlob( inputStream, inputStream.available() );
|
||||||
|
@ -154,7 +175,6 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor<Blob> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
throw unknownWrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,8 @@ import java.sql.Blob;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,8 @@ import java.io.StringReader;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,9 +27,11 @@ import java.io.Serializable;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.ClobImplementer;
|
||||||
import org.hibernate.engine.jdbc.ClobProxy;
|
import org.hibernate.engine.jdbc.ClobProxy;
|
||||||
import org.hibernate.engine.jdbc.WrappedClob;
|
import org.hibernate.engine.jdbc.WrappedClob;
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,8 +104,15 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor<Clob> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( CharacterStream.class.isAssignableFrom( type ) ) {
|
if ( CharacterStream.class.isAssignableFrom( type ) ) {
|
||||||
|
if ( ClobImplementer.class.isInstance( value ) ) {
|
||||||
|
// if the incoming Clob is a wrapper, just pass along its CharacterStream
|
||||||
|
return (X) ( (ClobImplementer) value ).getUnderlyingStream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise we need to build one...
|
||||||
return (X) new CharacterStreamImpl( DataHelper.extractString( value ) );
|
return (X) new CharacterStreamImpl( DataHelper.extractString( value ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final Clob clob = WrappedClob.class.isInstance( value )
|
final Clob clob = WrappedClob.class.isInstance( value )
|
||||||
? ( (WrappedClob) value ).getWrappedClob()
|
? ( (WrappedClob) value ).getWrappedClob()
|
||||||
|
|
|
@ -34,8 +34,9 @@ import java.sql.SQLException;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A help for dealing with BLOB and CLOB data
|
* A help for dealing with BLOB and CLOB data
|
||||||
|
|
|
@ -30,7 +30,8 @@ import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,8 @@ import java.io.StringReader;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,8 +30,9 @@ import java.sql.Blob;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||||
import org.hibernate.internal.util.SerializationHelper;
|
import org.hibernate.internal.util.SerializationHelper;
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,8 @@ import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
|
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.BinaryStream;
|
import org.hibernate.engine.jdbc.BinaryStream;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.CharacterStream;
|
import org.hibernate.engine.jdbc.CharacterStream;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
@ -80,7 +80,7 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor {
|
||||||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
|
final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
|
||||||
st.setCharacterStream( index, characterStream.getReader(), characterStream.getLength() );
|
st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue