/**
* Customised version of {@link org.hibernate.type.MaterializedNClobType} that forces use of NCLOB_BINDING (setNClob)
* so that unicode characters can be persisted in a JPA field text field (with database column type nclob).
* The original version used NClobTypeDescriptor.DEFAULT which ends up using streams (hibernate.jdbc.use_streams_for_binary) not setNClob,
* and the stream handling uses setCharacterStream (where it should use setNCharacterStream).
* The original version also has a bug in the StringDescriptor that would always shortcut at Clob (rather than NClob) type.
*
*/
public class MaterializedNClobType extends AbstractSingleColumnStandardBasicType<String> {
public static final MaterializedNClobType INSTANCE = new MaterializedNClobType();
public MaterializedNClobType() {
super ( STREAM_BINDING, StringTypeDescriptor.INSTANCE );
}
public String getName() {
return "materialized_nclob";
}
public static final NClobTypeDescriptor STREAM_BINDING =
new NClobTypeDescriptor() {
@Override
public <X> BasicBinder<X> getNClobBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder< X>( javaTypeDescriptor, this ) {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream. class, options );
st.setNCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
}
};
}
};
public MaterializedNClobType() {
super( NClobTypeDescriptor.NCLOB_BINDING, StringNClobTypeDescriptor.INSTANCE );
}
public static class StringNClobTypeDescriptor extends StringTypeDescriptor {
public static StringNClobTypeDescriptor INSTANCE = new StringNClobTypeDescriptor();
@Override
public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
if ( value == null ) {
return null;
}
if ( DataHelper.isNClob(type) ) {
return (X) options.getLobCreator().createNClob( value );
}
throw unknownUnwrap( type );
}
}
}