Re: Hibernate:使用用户定义的类型转换CLOB到String(setCharacte...

阅读更多
终于可以发贴了,在http://www.matrix.org.cn/thread.shtml?topicId=32938&forumId=23上给出问题,竞没人回话,先说问题吧!
我在自己定义的用户类型中遇到下面的问题:
下面这个函数读出数据没有问题:
public Object nullSafeGet(ResultSet resultSet, String[] stringArray,
Object object) throws HibernateException,
SQLException {
Reader reader = resultSet.getCharacterStream(stringArray[0]);
if (reader == null) return null;

StringBuffer sb = new StringBuffer();
try {
char[] charbuf = new char[4096];
//解决4096字节大小的限制
for (int i = reader.read(charbuf); i >0; i= reader.read(charbuf)) {
sb.append(charbuf, 0, i);
}
}
catch (IOException e) {
throw new SQLException( e.getMessage() );
}
return sb.toString();
}
//下面的函数写入数据总是不正确
public void nullSafeSet(PreparedStatement preparedStatement, Object object,
int _int) throws HibernateException, SQLException {
try{
if (object != null) {
// StringReader r = new StringReader( (String) object);
//下面的方法写入太多的数据会使CLOB为空,几百个字节没有问题
/* preparedStatement.setCharacterStream(_int, r,
( (String) object).length());*/

preparedStatement.setCharacterStream(_int,
new InputStreamReader(new ByteArrayInputStream(((String) object).getBytes())),
( (String) object).length());
System.out.println( (String) object+((String) object).length());
//下面的方法写入数据的长度有限制
// preparedStatement.setString(_int,(String) object);
} else {
preparedStatement.setNull(_int, sqlTypes()[0]);
// preparedStatement.setClob(1,Hibernate.createClob(" "));
}

}catch(Exception e){
e.printStackTrace();
}
我使用的是JB2005(编译器),Oracle 9.2.0.1.0(企业版),Hibernate 3.0,JDBC thin驱动
我也看过很多有关的贴(读取CLOB相关的),JAVA视线论坛,Hibernate官方站点的
(http://www.hibernate.org/76.html,http://www.hibernate.org/56.html)
Oracle官方站点等等.都没有找到合适的解决方案(或许我的悟性太差了)

还有如果使用OCI驱动连接老是有问题:
thin: jdbc:oracle:thin:@192.168.0.18:1521:plan 正确
OCI: jdbc:oracle:oci9:@192.168.0.18:1521:plan 找不到URL这个的错误
提示:我的机子其实装了oracle,由于内存太小(256M),所以数据库没有在本机上.
这还需要装oracle客户端吗?

另外我的配置有的也按照网上朋友所说的做了:
0
true


org.hibernate.dialect.Oracle9Dialect


请各位指点迷津,注意这里我只想使用自定义的用户类型方式实现CLOB到String的转换!

请看了此贴的朋友,如果可以解决说说解决办法,或是思想,不能解决的能给我一点建议!

初学JAVA时间不长,学HIBERNATE的时间就更短了,难免犯些低级的错误,请不要笑话!
------------------------------------------------------------------------------------------------------------------------------------------

第一种:
//          StringReader r = new StringReader( (String) object);
//下面的方法写入太多的数据会使CLOB为空,几百个字节没有问题
/*          preparedStatement.setCharacterStream(_int, r,
                                               ( (String) object).length());*/

          preparedStatement.setCharacterStream(_int,
              new InputStreamReader(new ByteArrayInputStream(((String) object).getBytes())),
                                               ( (String) object).length());

第二种:
//下面的方法写入数据的长度有限制
//          preparedStatement.setString(_int,(String) object);         
第三种:
会抛出无法从套接子读取太多数据的异常
我看了一些帖子说先要清楚,可在这里如何才能获得要清空的那个CLOB呢?
而下面的代码只是创建一个临时CLOB,然后对其写入数据,然后setClob().
      DatabaseMetaData dbMetaData = ps.getConnection().getMetaData();
      log.debug(dbMetaData.getDriverName());
      log.debug(dbMetaData.getDriverMajorVersion() + " " + dbMetaData.getDriverMinorVersion());
      log.debug(dbMetaData.getConnection().getClass().getName());

      if (value == null) {
          ps.setNull(index, sqlTypes()[0]);
      } else if (ORACLE_DRIVER_NAME.equals(dbMetaData.getDriverName())) {
          if ((dbMetaData.getDriverMajorVersion() >= ORACLE_DRIVER_MAJOR_VERSION) &&
                  (dbMetaData.getDriverMinorVersion() >= ORACLE_DRIVER_MINOR_VERSION)) {
              try {
                  // Code compliments of Scott Miller
                  // support oracle clobs without requiring oracle libraries
                  // at compile time
                  // Note this assumes that if you are using the Oracle Driver.
                  // then you have access to the oracle.sql.CLOB class
                  // First get the oracle clob class
                  Class oracleClobClass = Class.forName("oracle.sql.CLOB");

                  // Get the oracle connection class for checking
                  Class oracleConnectionClass = Class.forName("oracle.jdbc.OracleConnection");

                  // now get the static factory method
                  Class[] partypes = new Class[3];
                  partypes[0] = Connection.class;
                  partypes[1] = Boolean.TYPE;
                  partypes[2] = Integer.TYPE;
                  Method createTemporaryMethod = oracleClobClass.getDeclaredMethod("createTemporary", partypes);

                  // now get ready to call the factory method
                  Field durationSessionField = oracleClobClass.getField("DURATION_SESSION");
                  Object[] arglist = new Object[3];

                  //changed from: Connection conn = ps.getConnection();
                  Connection conn = dbMetaData.getConnection();

                  // Make sure connection object is right type
                  if (!oracleConnectionClass.isAssignableFrom(conn.getClass())) {
                      throw new HibernateException("JDBC connection object must be a oracle.jdbc.OracleConnection. " +
                          "Connection class is " + conn.getClass().getName());
                  }

                  arglist[0] = conn;
                  arglist[1] = Boolean.TRUE;
                  arglist[2] = durationSessionField.get(null); //null is valid because of static field

                  // Create our CLOB
                  Object tempClob = createTemporaryMethod.invoke(null, arglist); //null is valid because of static method

                  // get the open method
                  partypes = new Class[1];
                  partypes[0] = Integer.TYPE;

                  Method openMethod = oracleClobClass.getDeclaredMethod("open", partypes);

                  // prepare to call the method
                  Field modeReadWriteField = oracleClobClass.getField("MODE_READWRITE");
                  arglist = new Object[1];
                  arglist[0] = modeReadWriteField.get(null); //null is valid because of static field

                  // call open(CLOB.MODE_READWRITE);
                  openMethod.invoke(tempClob, arglist);
                  // get the getCharacterOutputStream method
                  Method getCharacterOutputStreamMethod = oracleClobClass.getDeclaredMethod("getCharacterOutputStream",
                          null);

                  // call the getCharacterOutpitStream method
                  Writer tempClobWriter = (Writer) getCharacterOutputStreamMethod.invoke(tempClob, null);

                  // write the string to the clob
                  tempClobWriter.write((String) value);
                  tempClobWriter.flush();
                  tempClobWriter.close();

                  // get the close method
                  Method closeMethod = oracleClobClass.getDeclaredMethod("close", null);

                  // call the close method
                  closeMethod.invoke(tempClob, null);

                  // add the clob to the statement
                  ps.setClob(index, (Clob) tempClob);

                  LobCleanUpInterceptor.registerTempLobs(tempClob);
              } catch (ClassNotFoundException e) {
                  // could not find the class with reflection
                  throw new HibernateException("Unable to find a required class.\n" + e.getMessage());
              } catch (NoSuchMethodException e) {
                  // could not find the metho with reflection
                  throw new HibernateException("Unable to find a required method.\n" + e.getMessage());
              } catch (NoSuchFieldException e) {
                  // could not find the field with reflection
                  throw new HibernateException("Unable to find a required field.\n" + e.getMessage());
              } catch (IllegalAccessException e) {
                  throw new HibernateException("Unable to access a required method or field.\n" + e.getMessage());
              } catch (InvocationTargetException e) {
                  throw new HibernateException(e.getMessage());
              } catch (IOException e) {
                  throw new HibernateException(e.getMessage());
              }
          } else {
              throw new HibernateException("No CLOBS support. Use driver version " + ORACLE_DRIVER_MAJOR_VERSION +
                  ", minor " + ORACLE_DRIVER_MINOR_VERSION);
          }
      } else {
          String str = (String) value;
          StringReader r = new StringReader(str);
          ps.setCharacterStream(index, r, str.length());
      }             
注意:LobCleanUpInterceptor我已经实现,并且在openSession()时这样写的openSession(new LobCleanUpInterceptor())

你可能感兴趣的:(Hibernate,Oracle,JDBC,笑话,SQL)