我需要使用Hibernate从Clob Oracle列中获取字符串,而无需延迟加载并且不使用Criteria查询。它当前返回一个代理类(例如$ Proxy30),但是我需要一个字符串(或者可以转换为字符串的东西)。根据调试器,该代理用于oracle.sql.CLOB。

当我使用Criteria查询(仅对该字段使用常规的Column注释映射)时,这很好。但是,在一个区域中,我们“构建”了一个自定义SQL查询,该查询使用简单的org.hibernate.Query和AliasToEntityMapResultTransformer.INSTANCE,这就是发生代理问题的地方。由于它只是一个org.hibernate.Query,因此我认为它根本没有引用我的注释映射,因此我认为弄乱注释不会有任何帮助。

由于此处不提供使用条件查询的选项(我们正在为一些高级搜索报告要求构建查询字符串),因此我应该研究什么才能找到解决方法?甚至更好,我为此付出最少的努力是什么?

这也适用于Apache Flex应用程序-我需要类型为String(而不是CLOB)以用于到客户端的数据传输对象中。也许其他Flex开发人员以前已经解决了这个问题?

Query query = getSessionFactory().getCurrentSession().createSqlQuery(sql);
query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List... resultlist = ...query.list();
resultlist.iterator();
//iterate results...
Object shouldBeAString = (Object)result.get("CLOB_COLUMN_NAME");
//The object above should be a String but is a $Proxy30
//Debugger shows an "h" property of type SerializableClobProxy


如果我需要一个自定义的“ ResultTransformer”-进行此操作的任何指向体面文档的链接,将不胜感激...

最佳答案

我只是遇到了同样的问题,各种链接建议将spring升级到4.0.1+,然后将其休眠到4.3.x,但这没有任何区别。然后我遇到了这个链接,它解决了我的问题。作者为Clob编写了一个自定义ResultTransformer,然后将其设置为您查询的转换器,而不是AliasToEntityMapResultTransformer。

http://javatechtricks.blogspot.co.uk/2012/12/hibernate-clob-to-string-conversion.html

来自以下文章的代码:

public class MyResultTransformer extends BasicTransformerAdapter {

 public final static MyResultTransformer INSTANCE;
 static {
  INSTANCE = new MyResultTransformer();
 }

 private MyResultTransformer() {

 }
 private static final long serialVersionUID = 1L;

 @Override
 public Object transformTuple(Object[] tuple, String[] aliases) {
  Map<String, Object> map = new HashMap<String, Object>();
  for (int i = 0; i < aliases.length; i++) {
   Object t = tuple[i];
   if (t != null && t instanceof Clob) {
    Clob c = (Clob) tuple[i];
    try {
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     IOUtils.copy(c.getAsciiStream(), bos);
     t = new String(bos.toByteArray());
    } catch (SQLException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   map.put(aliases[i], t);
  }
  return map;
 }
}


然后在您的代码中替换

query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);




query.setResultTransformer(MyResultTransformer.INSTANCE);


另外,另一种解决方案可能是更改列类型,我自己没有尝试过。


  JDBC大对象
  blob和clob类型为
  java.sql包中的Blob和Clob类。如果您正在处理
  真正大的值,最好的选择是将属性声明为
  Blob或Clob-即使这引入了显式的JDBC
  依赖于您的数据对象,它很容易允许Hibernate利用
  JDBC功能仅在需要时才延迟加载属性值。
  
  如果您不担心数据太大,则可以保留
  您自己这个直接的JDBC接口,将属性类型声明为
  字符串或字节[],并使用文本或二进制将其映射。这些对应
  到CLOB和VARBINARY的SQL列类型(在Oracle中为RAW,在
  PostgreSQL),并将值立即加载到
  加载对象时的属性。


资料来源:http://oreilly.com/java/excerpts/harnessing-hibernate/hibernate-types.html

关于java - 在Hibernate org.hibernate.Query中将Clob数据作为字符串加载(渴望),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23581549/

10-11 05:05