在where子句中使用带有clob参数的函数

时间:2013-11-20 15:36:10

标签: oracle hibernate jpa

我们正在使用@NamedNativeQuery从我们的数据库中获取由查询的where子句中的存储过程flexmatch限定的实体。

这通常很好用,但是当参数chimeString超过4.000个字符时,它无法引发以下异常:

  

ORA-01460:请求未执行或无理转换

这是有道理的,因为4.000个字符是Oracle在Clob和Clob之间的边界。

我们尝试

  1. 使用org.hibernate.engine.jdbc.ClobProxy

    return entityManager
        .createNamedQuery("Structure.findByExactMatch", Structure.class)
        .setParameter("chime", ClobProxy.generateProxy(chimeString))
        .getResultList();
    
  2. javax.persistence.criteria.ParameterExpressionorg.hibernate.engine.jdbc.ClobProxy

    一起使用
    ParameterExpression<Clob> chimeParam = entityManager
        .getCriteriaBuilder()
        .parameter(Clob.class, "chime");
    return entityManager
        .createNamedQuery("Structure.findByExactMatch", Structure.class)
        .setParameter(chimeParam, ClobProxy.generateProxy(chimeString))
        .getResultList();
    
  3. 图书馆&amp;系统:

    • Oracle 11g
    • Hibernate 3.6.6

    查找方法。

    public List<Structure> findByExactMatch(String chimeString) {
      return entityManager
          .createNamedQuery("Structure.findByExactMatch", Structure.class)
          .setParameter("chime", chimeString)
          .getResultList();
    }
    

    结构实体。

    @Entity
    @NamedNativeQueries({
      @NamedNativeQuery(
        name = "Structure.findByExactMatch",
        query = "SELECT id, molfile(ctab) ctab FROM structure " + 
                "WHERE flexmatch(ctab, :chime, 'all')=1",
        resultClass = Structure.class) })
    public class Structure {
    
      @Id
      @Column(name = "ID")
      private long id;
    
      @Lob
      @Column(name = "CTAB")
      private String ctab;
    
      // getter & setter
    
    }
    

    编辑1 pl / sql函数,因为您可以看到它已经过载。

    FUNCTION flexmatch(
        molobj IN BLOB, 
        querymol IN VARCHAR2,
        args IN VARCHAR2)
    RETURN NUMBER
    
    FUNCTION Flexmatch(
        molobj IN BLOB, 
        querymol IN CLOB,
        args IN VARCHAR2)
    RETURN NUMBER
    

1 个答案:

答案 0 :(得分:0)

经过几天的尝试,我们放弃了在Hiberante内解决它。我们使用SpringJDBC运行查询,SpringJDBC也存在于项目中,并使用ID填充Hiberante实体。你也可以用普通的旧JDBC做到这一点。

相关问题