Gavin,

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;
  }
}

Reply via email to