简体   繁体   English

如何使用Hibernate / JPA调用返回字符串的Oracle函数?

[英]Howto call Oracle function which returns a string using Hibernate/JPA?

I want to call a Oracle function using JPA. 我想使用JPA调用Oracle函数。 I found this thread on this topic. 我在这个主题上找到了这个主题。

But my Oracle function only returns a string. 但我的Oracle函数只返回一个字符串。 Not the result for some kind of entity. 不是某种实体的结果。 I tried something like this: 我试过这样的事情:

@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") }
)

When I call the query like this 当我这样调用查询时

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

I get 我明白了

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)

Any ideas? 有任何想法吗?

We ended up using a CallableStatement . 我们最终使用了CallableStatement It works, but tell me if there's a better solution! 它有效,但告诉我是否有更好的解决方案!

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

I do it a rather hacky way, you have to return a refcursor. 我这是一个相当hacky的方式,你必须返回一个refcursor。 So make sure your function returns a ref cursors and does something like below : 因此,请确保您的函数返回ref游标并执行以下操作:

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

then create a "dummy" entity 然后创建一个“虚拟”实体

@Entity
public class NativeString {
    private String str;

    @Id
    @Column(name = "str")
    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
}

and you can use the native query functionality 并且您可以使用本机查询功能

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

        )

})

This is about as ugly as it gets... there is not nice way afaik with hierbnate and stored procedures and functions. 这就像它得到的那样丑陋......对于hierbnate和存储过程和函数来说,没有好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM