I know I've reported that Hibernate works with CLOB's, but I'm afraid that I was wrong. Hibernate persists Strings into CLOB columns perfectly fine, but reading it out of the db yields a null. I've added a new ClobType to handle CLOB columns to treat them as Strings. I've attached a diff and the new file.
I'm not sure that this is the right thing to do, because some may want direct access to the Clob object, or would prefer a Reader (in which case the setter ought to be a Writer), which would be a lot more complicated. If we go with the former, Hibernate would need to implement it's own Clob object. What do you think?
-Mark
? build
? patch.diff
? cirrus/hibernate/type/ClobType.java
? lib/j2ee.jar
? lib/junit.jar
Index: cirrus/hibernate/Hibernate.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/Hibernate.java,v
retrieving revision 1.59
diff -c -r1.59 Hibernate.java
*** cirrus/hibernate/Hibernate.java 5 Oct 2002 04:18:30 -0000 1.59
--- cirrus/hibernate/Hibernate.java 16 Oct 2002 08:02:56 -0000
***************
*** 50,55 ****
--- 50,59 ----
*/
public static final NullableType STRING = new StringType();
/**
+ * Hibernate <tt>clob</tt> type
+ */
+ public static final NullableType CLOB = new ClobType();
+ /**
* Hibernate <tt>time</tt> type
*/
public static final NullableType TIME = new TimeType();
Index: cirrus/hibernate/impl/SessionImpl.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/impl/SessionImpl.java,v
retrieving revision 1.128
diff -c -r1.128 SessionImpl.java
*** cirrus/hibernate/impl/SessionImpl.java 15 Oct 2002 16:04:05 -0000 1.128
--- cirrus/hibernate/impl/SessionImpl.java 16 Oct 2002 08:03:04 -0000
***************
*** 1002,1008 ****
}
else if ( old!=null ) {
throw new HibernateException(
! "Another object was associated with this id (the
object with the given id was already loaded)"
);
}
--- 1002,1009 ----
}
else if ( old!=null ) {
throw new HibernateException(
! "Another object of " + object.getClass().toString() +
! " has already been loaded with the id " + id
);
}
Index: cirrus/hibernate/sql/OracleDialect.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/sql/OracleDialect.java,v
retrieving revision 1.25
diff -c -r1.25 OracleDialect.java
*** cirrus/hibernate/sql/OracleDialect.java 2 Oct 2002 06:27:55 -0000 1.25
--- cirrus/hibernate/sql/OracleDialect.java 16 Oct 2002 08:03:05 -0000
***************
*** 31,36 ****
--- 31,37 ----
register( Types.TIMESTAMP, "DATE" );
register( Types.VARBINARY, "RAW($l)" );
register( Types.NUMERIC, "NUMBER(19, $l)" );
+ register( Types.CLOB, "CLOB" );
outerJoinGenerator = new OracleOuterJoinGenerator();
Index: cirrus/hibernate/type/TypeFactory.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/type/TypeFactory.java,v
retrieving revision 1.20
diff -c -r1.20 TypeFactory.java
*** cirrus/hibernate/type/TypeFactory.java 5 Oct 2002 09:33:42 -0000 1.20
--- cirrus/hibernate/type/TypeFactory.java 16 Oct 2002 08:03:06 -0000
***************
*** 39,44 ****
--- 39,45 ----
basics.put( Hibernate.CHARACTER.getName(), Hibernate.CHARACTER);
basics.put( Hibernate.INTEGER.getName(), Hibernate.INTEGER);
basics.put( Hibernate.STRING.getName(), Hibernate.STRING);
+ basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB);
basics.put( Hibernate.DATE.getName(), Hibernate.DATE);
basics.put( Hibernate.TIME.getName(), Hibernate.TIME);
basics.put( Hibernate.TIMESTAMP.getName(), Hibernate.TIMESTAMP);
//$Id: ClobType.java,v 1.17 2002/10/11 05:39:15 oneovthafew Exp $ package cirrus.hibernate.type;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class ClobType extends ImmutableType implements DiscriminatorType {
public Object get(ResultSet rs, String name) throws SQLException {
Clob clob = rs.getClob(name);
if (clob != null) {
long len = clob.length();
if (len > Integer.MAX_VALUE) {
long idx = 1;
StringBuffer buf = new StringBuffer();
while (idx < len) {
long diff = len - idx;
if (diff > Integer.MAX_VALUE) {
buf.append(clob.getSubString(idx, Integer.MAX_VALUE));
idx += Integer.MAX_VALUE;
} else {
buf.append(clob.getSubString(idx, (int)(diff + 1)));
idx += diff;
}
}
return buf.toString();
} else {
return clob.getSubString(1, (int)len);
}
}
return null;
}
public Class returnedClass() {
return String.class;
}
public void set(PreparedStatement st, Object value, int index) throws SQLException {
st.setString(index, (String) value);
}
public int sqlType() {
return Types.CLOB;
}
public String getName() { return "clob"; }
public String objectToSQLString(Object value) throws Exception {
return '\'' + (String) value + '\'';
}
public Object stringToObject(String xml) throws Exception {
return xml;
}
public boolean equals(Object x, Object y) {
if (x==y) return true;
if (x==null || y==null) return false;
// don't have to check class for String
return x.equals(y);
}
public String toXML(Object value) {
return (String) value;
}
}
