【问题标题】:Howto call Oracle function which returns a string using Hibernate/JPA?如何调用使用 Hibernate/JPA 返回字符串的 Oracle 函数?
【发布时间】:2013-12-06 07:52:00
【问题描述】:

我想使用 JPA 调用 Oracle 函数。我在这个话题上找到了this thread

但我的 Oracle 函数只返回一个字符串。不是某种实体的结果。我试过这样的事情:

@NamedNativeQuery(name = "myFuncCall",
        resultSetMapping = "myResultSetMapping",
        query = "{ ? = call schema.mypkg.somefunc(:id) }",
        hints = { @javax.persistence.QueryHint(name = "org.hibernate.callable", value = "true") }
)

@SqlResultSetMapping(name = "myResultSetMapping",
    columns = { @ColumnResult(name="somename") }
)

当我这样调用查询时

Query query = em.createNamedQuery("myFuncCall", String.class).setParameter("id", "42");
        String res = (String) query.getSingleResult();

我明白了

Hibernate: { ? = call schema.somefunc(?) }
18:21:11.222 [main] WARN  o.h.util.JDBCExceptionReporter - SQL Error: 6550, SQLState: 65000
18:21:11.222 [main] ERROR o.h.util.JDBCExceptionReporter - ORA-06550: Row 1, Column 13:
PLS-00382: This expression has the wrong type
ORA-06550: Row 1, Column 7:
PL/SQL: Statement ignored

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1317)
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:307)

有什么想法吗?

【问题讨论】:

  • 你有没有找到任何对这个有用的东西,我也一起破解了其他东西
  • 不,还是和下面一样,很遗憾。

标签: java hibernate jpa


【解决方案1】:

我们最终使用了@987654321@。它有效,但请告诉我是否有更好的解决方案!

String funcCall = "{? = call schema.mypkg.somefunc(?)}";
Connection conn = ((SessionImpl)em.getDelegate()).connection();
CallableStatement stmt = conn.prepareCall(funcCall);
stmt.setInt(2, 42);
stmt.registerOutParameter(1, Types.CHAR);
stmt.executeUpdate();
String result = stmt.getString(1);

【讨论】:

    【解决方案2】:

    我这样做是一种相当老套的方式,你必须返回一个 refcursor。因此,请确保您的函数返回一个 ref 游标并执行如下操作:

    result_string := doSoemthing
        open l_refcursor for select result_string as str from dual;
        return l_refcursor;
    

    然后创建一个“虚拟”实体

    @Entity
    public class NativeString {
        private String str;
    
        @Id
        @Column(name = "str")
        public String getStr() {
            return str;
        }
    
        public void setStr(String str) {
            this.str = str;
        }
    }
    

    您可以使用本机查询功能

    @NamedNativeQueries({
            @javax.persistence.NamedNativeQuery(name = "whatevs", query = "" +
                    "{? =  call myfunction(:id)}", resultClass = NativeString.class,
                    hints = {
                            @javax.persistence.QueryHint(name = "org.hibernate.callable", value = "true")
                    }
    
            )
    
    })
    

    这几乎是丑陋的......没有很好的方法 afaik 与 hierbnate 和存储过程和函数。

    【讨论】:

      猜你喜欢
      • 2018-04-23
      • 2010-12-14
      • 2012-09-15
      • 2012-12-29
      • 2012-12-12
      • 2011-10-22
      • 2015-11-29
      • 2015-10-13
      • 2023-03-14
      相关资源
      最近更新 更多