Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JPA执行数据库功能_Java_Hibernate_Jpa_Entitymanager - Fatal编程技术网

Java 使用JPA执行数据库功能

Java 使用JPA执行数据库功能,java,hibernate,jpa,entitymanager,Java,Hibernate,Jpa,Entitymanager,要调用Oracle数据库函数,我只需编写 final Query query = entityManager.createNativeQuery( "select myfunction(?) from dual" ); query.setParameter(1, "value"); Object rv = query.getSingleResult(); 只要被调用的函数不执行任何dml操作,这就可以工作。 否则我就得执行类似的命令 {? = call myfunction(?

要调用Oracle数据库函数,我只需编写

final Query query = entityManager.createNativeQuery(
    "select myfunction(?) from dual"
);
query.setParameter(1, "value");
Object rv = query.getSingleResult();
只要被调用的函数不执行任何dml操作,这就可以工作。 否则我就得执行类似的命令

    {? = call myfunction(?)}
不幸的是,我无法注册任何OUT参数,因此无法使此语句正常工作。 如果不使用普通的JDBC,如何实现这一点


编辑:

这个问题具有误导性。我想在Oracle数据库中获取函数(而不是存储过程)的结果。没有输出参数。函数可以如下所示:

CREATE OR REPLACE FUNCTION myfunction(value IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
    UPDATE foo SET bar = 'foobar'
    WHERE id = 1;

    RETURN 'test';
END myfunction;
的答案不能解决我的问题,因为我的函数中有dml更改。我得到一个错误:

无法在查询内执行DML操作


您必须使用StoredProcedureQuery:

StoredProcedureQuery query = this.em.createStoredProcedureQuery("myfunction");
query.registerStoredProcedureParameter("inparam", String.class, ParameterMode.IN);
query.registerStoredProcedureParameter("outparam", String.class, ParameterMode.OUT);

// set input parameter
query.setParameter("inparam", "Hello);

// call the stored procedure and get the result
query.execute();
String result = (String) query.getOutputParameterValue("sum");
如果您希望得到一个或多个结果,可以使用

getSingleResult() or getResultList() 
类似于查询接口,而不是getOutputParameterValue()

请在此处查找更多信息:

  • 当函数中有任何DML语句时,Select查询将不起作用。
    如果没有DML语句,则SELECT查询是最佳和高效的继续方式
  • 如果有DML语句,则必须使用接口CallableStatement。
    当我们在项目中使用JDBC时,这是非常进步的,但是对于Spring项目,即使用JPA,我们需要从EntityManager和ReturningWork获得会话
Session Session=entityManager.unwrap(Session.class);
CallableStatement CallableStatement=session.doReturningWork(新的ReturningWork()){
@凌驾
公共CallableStatement执行(连接)引发SQLException{
CallableStatement函数=connection.prepareCall(
{?=调用包的名称。函数的名称(?,)};
registerOutParameter(1,Types.INTEGER);
setLong函数(2,56);
function.setString(3,“某些文本”);
函数execute();
返回函数;
}
});
试一试{
返回callableStatement.getBigDecimal(1);
}捕获(SQLE异常){
e、 printStackTrace();
返回null;
}

可能与@anste重复您是如何解决的。我陷入了同样的困境issue@Ismail不幸的是,我没有解决这个问题。在可能的情况下,我将函数更改为带有OUT参数的过程。或者,您可以创建一个包装过程,该过程调用函数并将结果放入out参数中。@anste我已经解决了它。我没有找到任何使用JPA的解决方案,所以我不得不使用JDBC CallableStatement。我将把它添加到我编辑的问题的答案中。我想获取函数的返回值,而不是任何OUT参数。查询界面上有getResultList()和getSingleResult。请查看文档谢谢您的帮助,但我无法使其正常工作。Hibernate总是创建一个类似“{call myfunction(?)}”的语句。因此,需要一个过程,我得到“myfunction不是过程或未定义”。你能举个例子吗?我相信当使用
createStoredProcedureCall
CreateStoredProcedureRequesty
时,查询会转换成
“{call myfunction(?)}”
。如果只需要返回,那么只需使用
createNativeQuery
@coladict如果不使用select,使用createNativeQuery的解决方案会是什么样子?
  Session session = entityManager.unwrap(Session.class);
      CallableStatement callableStatement =  session.doReturningWork(new ReturningWork<CallableStatement>() {
            @Override
            public CallableStatement execute(Connection connection) throws SQLException {
                CallableStatement function = connection.prepareCall(
                        "{ ? = call package_name.function_name(?,?) }");
                function.registerOutParameter(1, Types.INTEGER);
                function.setLong(2, 56);
                function.setString(3,"some text");

                function.execute();
                return function;
            }
        });

        try {
            return callableStatement.getBigDecimal(1);
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }