我想使用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)
有什么想法吗?
答案 0 :(得分:2)
我们最终使用CallableStatement
。它有效,但告诉我是否有更好的解决方案!
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);
答案 1 :(得分:0)
我是一个相当hacky的方式,你必须返回一个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")
}
)
})
这就像它得到的一样丑陋......没有很好的方法来支持hierbnate和存储过程和函数。