Skip to content

Commit f9e544e

Browse files
committed
improve javadoc
experiment with transferTo() to copy Blob/Clob streams instead of getSubString() Signed-off-by: Gavin King <[email protected]>
1 parent 35b97a0 commit f9e544e

File tree

3 files changed

+105
-20
lines changed

3 files changed

+105
-20
lines changed

hibernate-core/src/main/java/org/hibernate/engine/jdbc/LobCreator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ public interface LobCreator {
108108
* Return an instance which can actually be written to a JDBC
109109
* {@code PreparedStatement}.
110110
*
111+
* @see java.sql.PreparedStatement#setBlob(int, Blob)
112+
*
111113
* @apiNote This is needed for Oracle
112114
*
113115
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob
@@ -120,6 +122,8 @@ public interface LobCreator {
120122
* Return an instance which can actually be written to a JDBC
121123
* {@code PreparedStatement}.
122124
*
125+
* @see java.sql.PreparedStatement#setClob(int, Clob)
126+
*
123127
* @apiNote This is needed for Oracle
124128
*
125129
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob
@@ -132,6 +136,8 @@ public interface LobCreator {
132136
* Return an instance which can actually be written to a JDBC
133137
* {@code PreparedStatement}.
134138
*
139+
* @see java.sql.PreparedStatement#setNClob(int, NClob)
140+
*
135141
* @apiNote This is needed for Oracle
136142
*
137143
* @see org.hibernate.dialect.Dialect#useConnectionToCreateLob

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/BlobAndClobCreator.java

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.sql.Clob;
1111
import java.sql.Connection;
1212
import java.sql.NClob;
13+
import java.sql.ResultSet;
1314
import java.sql.SQLException;
1415

1516
import org.hibernate.JDBCException;
@@ -37,6 +38,11 @@ public class BlobAndClobCreator extends AbstractLobCreator implements LobCreator
3738
*/
3839
public static final LobCreationContext.Callback<Clob> CREATE_CLOB_CALLBACK = Connection::createClob;
3940

41+
/**
42+
* Callback for performing contextual NCLOB creation
43+
*/
44+
public static final LobCreationContext.Callback<NClob> CREATE_NCLOB_CALLBACK = Connection::createNClob;
45+
4046
protected final LobCreationContext lobCreationContext;
4147
protected final boolean useConnectionToCreateLob;
4248

@@ -54,6 +60,10 @@ Blob createBlob() {
5460
return lobCreationContext.fromContext( CREATE_BLOB_CALLBACK );
5561
}
5662

63+
/**
64+
* Create a {@link Blob} object after reading a {@code byte[]}
65+
* array from a JDBC {@link ResultSet}.
66+
*/
5767
@Override
5868
public Blob createBlob(byte[] bytes) {
5969
final Blob blob = createBlob();
@@ -66,11 +76,18 @@ public Blob createBlob(byte[] bytes) {
6676
}
6777
}
6878

79+
/**
80+
* Create a {@link Blob} object after reading an {@link InputStream}
81+
* from a JDBC {@link ResultSet}.
82+
*
83+
* @implNote
84+
* It's very inefficient to use JDBC LOB locator creation to create
85+
* a LOB with the contents of the given stream, since that requires
86+
* reading the whole stream. So instead just wrap the given stream,
87+
* just like what {@link NonContextualLobCreator} does.
88+
*/
6989
@Override
7090
public Blob createBlob(InputStream stream, long length) {
71-
// IMPL NOTE: it's inefficient to use JDBC LOB locator creation to
72-
// create a LOB backed by a given stream. So just wrap the stream
73-
// (which is what the NonContextualLobCreator does).
7491
return NonContextualLobCreator.INSTANCE.createBlob( stream, length );
7592
}
7693

@@ -79,10 +96,23 @@ public Blob createBlob(InputStream stream, long length) {
7996
*
8097
* @return The created CLOB reference.
8198
*/
82-
public Clob createClob() {
99+
Clob createClob() {
83100
return lobCreationContext.fromContext( CREATE_CLOB_CALLBACK );
84101
}
85102

103+
/**
104+
* Create the basic contextual NCLOB reference.
105+
*
106+
* @return The created NCLOB reference.
107+
*/
108+
NClob createNClob() {
109+
return lobCreationContext.fromContext( CREATE_NCLOB_CALLBACK );
110+
}
111+
112+
/**
113+
* Create a {@link Clob} object after reading a {@code String}
114+
* from a JDBC {@link ResultSet}.
115+
*/
86116
@Override
87117
public Clob createClob(String string) {
88118
try {
@@ -95,11 +125,18 @@ public Clob createClob(String string) {
95125
}
96126
}
97127

128+
/**
129+
* Create a {@link Clob} object after reading an {@link InputStream}
130+
* from a JDBC {@link ResultSet}.
131+
*
132+
* @implNote
133+
* It's very inefficient to use JDBC LOB locator creation to create
134+
* a LOB with the contents of the given stream, since that requires
135+
* reading the whole stream. So instead just wrap the given stream,
136+
* just like what {@link NonContextualLobCreator} does.
137+
*/
98138
@Override
99139
public Clob createClob(Reader reader, long length) {
100-
// IMPL NOTE: it's inefficient to use JDBC LOB locator creation to
101-
// create a LOB backed by a given stream. So just wrap the stream
102-
// (which is what the NonContextualLobCreator does).
103140
return NonContextualLobCreator.INSTANCE.createClob( reader, length );
104141
}
105142

@@ -113,39 +150,81 @@ public NClob createNClob(Reader reader, long length) {
113150
return NonContextualLobCreator.INSTANCE.createNClob( reader, length );
114151
}
115152

153+
/**
154+
* Obtain a {@link Blob} instance which can be written to a JDBC
155+
* {@link java.sql.PreparedStatement} using
156+
* {@link java.sql.PreparedStatement#setBlob(int, Blob)}.
157+
*/
116158
@Override
117159
public Blob toJdbcBlob(Blob blob) {
118160
try {
119-
return useConnectionToCreateLob
120-
? createBlob( blob.getBytes( 1, (int) blob.length() ) )
121-
: super.toJdbcBlob( blob );
161+
if ( useConnectionToCreateLob ) {
162+
// final Blob jdbcBlob = createBlob();
163+
// blob.getBinaryStream().transferTo( jdbcBlob.setBinaryStream(1) );
164+
// return jdbcBlob;
165+
return createBlob( blob.getBytes( 1, (int) blob.length() ) );
166+
}
167+
else {
168+
return super.toJdbcBlob( blob );
169+
}
122170
}
123171
catch (SQLException e) {
124-
throw new JDBCException( "Could not create JDBC Clob", e );
172+
throw new JDBCException( "Could not create JDBC Blob", e );
125173
}
174+
// catch (IOException e) {
175+
// throw new HibernateException( "Could not create JDBC Blob", e );
176+
// }
126177
}
127178

179+
/**
180+
* Obtain a {@link Clob} instance which can be written to a JDBC
181+
* {@link java.sql.PreparedStatement} using
182+
* {@link java.sql.PreparedStatement#setClob(int, Clob)}.
183+
*/
128184
@Override
129185
public Clob toJdbcClob(Clob clob) {
130186
try {
131-
return useConnectionToCreateLob
132-
? createClob( clob.getSubString( 1, (int) clob.length() ) )
133-
: super.toJdbcClob( clob );
187+
if ( useConnectionToCreateLob ) {
188+
// final Clob jdbcClob = createClob();
189+
// clob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );
190+
// return jdbcClob;
191+
return createClob( clob.getSubString( 1, (int) clob.length() ) );
192+
}
193+
else {
194+
return super.toJdbcClob( clob );
195+
}
134196
}
135197
catch (SQLException e) {
136198
throw new JDBCException( "Could not create JDBC Clob", e );
137199
}
200+
// catch (IOException e) {
201+
// throw new HibernateException( "Could not create JDBC Clob", e );
202+
// }
138203
}
139204

205+
/**
206+
* Obtain an {@link NClob} instance which can be written to a JDBC
207+
* {@link java.sql.PreparedStatement} using
208+
* {@link java.sql.PreparedStatement#setNClob(int, NClob)}.
209+
*/
140210
@Override
141211
public NClob toJdbcNClob(NClob clob) {
142212
try {
143-
return useConnectionToCreateLob
144-
? createNClob( clob.getSubString( 1, (int) clob.length() ) )
145-
: super.toJdbcNClob( clob );
213+
if ( useConnectionToCreateLob ) {
214+
// final NClob jdbcClob = createNClob();
215+
// clob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );
216+
// return jdbcClob;
217+
return createNClob( clob.getSubString( 1, (int) clob.length() ) );
218+
}
219+
else {
220+
return super.toJdbcNClob( clob );
221+
}
146222
}
147223
catch (SQLException e) {
148-
throw new JDBCException( "Could not create JDBC Clob", e );
224+
throw new JDBCException( "Could not create JDBC NClob", e );
149225
}
226+
// catch (IOException e) {
227+
// throw new HibernateException( "Could not create JDBC NClob", e );
228+
// }
150229
}
151230
}

hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/LobCreatorBuilderImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static LobCreatorBuilderImpl makeLobCreatorBuilder(
5252
}
5353

5454
/**
55-
* For used when JDBC Connection is not available.
55+
* For use when JDBC {@link Connection} is not available.
5656
*
5757
* @return Appropriate LobCreatorBuilder
5858
*/
@@ -62,7 +62,7 @@ public static LobCreatorBuilderImpl makeLobCreatorBuilder(Dialect dialect) {
6262
}
6363

6464
/**
65-
* Build a LobCreator using the given context
65+
* Build a {@link LobCreator} using the given context
6666
*
6767
* @param lobCreationContext The LOB creation context
6868
*

0 commit comments

Comments
 (0)