1010import java .sql .Clob ;
1111import java .sql .Connection ;
1212import java .sql .NClob ;
13+ import java .sql .ResultSet ;
1314import java .sql .SQLException ;
1415
1516import 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}
0 commit comments