【问题标题】:Hibernate Function returns ORA-14551休眠函数返回 ORA-14551
【发布时间】:2016-05-06 16:05:48
【问题描述】:

我正在尝试使用 Hibernate 4.3.11.Final 在 oracle 11g 中调用一个返回整数的函数,但当我尝试调用它时,它会抛出此异常:

 ORA-14551: cannot perform a DML operation inside a query

这是命名查询:

@NamedNativeQuery(name = "generaFolio",
        query = " { CALL GENERA_FOLIO( :idArea ) } ")

在函数内部有一个 CURSOR 和一个 UPDATE 语句

函数如下:

    create or replace FUNCTION GENERA_FOLIO 
        (
        areaorigen number
        ) return number
        as
        v_FOLIO      number;
        resource_busy EXCEPTION;
        timeout_expired EXCEPTION;

        PRAGMA EXCEPTION_INIT(timeout_expired,-30006);
        PRAGMA EXCEPTION_INIT (r

esource_busy, -54);

    cursor c1 is 
      select FOLIO FROM FOLIOS f1
        WHERE  
          folio = (select min(folio) from Folios f2 where f2.IDAREA = areaorigen and vlock='D')
          and f1.idarea = areaorigen 
          and vlock='D'
      for update nowait;

    BEGIN

         -- DBMS_OUTPUT.put_line('Folio para area :: ' || areaorigen);

         BEGIN
             open c1;
             fetch c1 into v_FOLIO;
             close c1;
         EXCEPTION
                 When no_data_found then
                 RAISE_APPLICATION_ERROR (-20001, 'No Existen datos en Folio-area : ' || areaorigen);
                 When timeout_expired then
                 RAISE_APPLICATION_ERROR (-20002, 'Tiempo de Espera consumido para area : ' || areaorigen);
                 When resource_busy then
                 RAISE_APPLICATION_ERROR (-20003, 'Folio bloqueado, para la area : ' || areaorigen);
                 When others then
                 RAISE_APPLICATION_ERROR (-20004, 'Fallo en el momento de tomar folio, de la sig. area: ' ||
                                          areaorigen ||  ' >> Error number ' || SQLCODE || ' >> ' || SQLERRM);
         end;

         --DBMS_OUTPUT.put_line('Folio a Bloquear :: ' || v_folio);

         UPDATE folios SET vlock = 'A'
         WHERE  IDAREA = areaorigen 
         and folio = v_FOLIO;

        --DBMS_OUTPUT.put_line('Folio a Bloqueado! ');

    return  v_FOLIO;
    end GENERA_FOLIO;

我的执行方式是:

Query query = getSession().getNamedQuery(queryName);    
setParameters(params, query);
Object uniqueResult = query.uniqueResult();

调用另一个返回 varchar2 并且内部只有 SELECT 的函数可以正常工作,

请帮忙:(

注意 1: 将查询声明为:

@NamedNativeQuery(name = "generaFolio", //
query = " { ? = CALL GENERA_FOLIO( :idArea ) } ") })

它抛出了这个错误:

org.hibernate.QueryException: Expected positional parameter count: 1, actual parameters: [] [{ ? = CALL GENERA_FOLIO( :idArea ) }]

因为据我了解,您可以通过位置(“?”)或标识符(“:idArea”)定义参数,而我只是设置一个:/

注意 2:

也试过这个:

How to call Oracle Function or Procedure using Hibernate 4 (EntityManager) or JPA 2

喜欢:

    @NamedNativeQuery(name = "generaFolio", //
    query = " { ? = CALL GENERA_FOLIO( :idArea ) } ", //
    hints = { @QueryHint(name = "org.hibernate.callable", value = "true") }),

    @NamedNativeQuery(name = "generaFolio2", //
    query = "{ call GENERA_FOLIO(?,:idArea) }", //
    hints = { @QueryHint(name = "org.hibernate.callable", value = "true") })

但在:

Object uniqueResult = query.getFirstResult();

两者都返回 NULL...

【问题讨论】:

  • 请编辑问题并包含您的程序代码,因为这就是错误所在。谢谢。
  • 为什么每次尝试运行命名查询时都执行CREATE or REPLACE?为什么不预先定义函数,然后调用函数来检索值?
  • 看起来休眠以某种方式尝试在内部执行select GENERA_FOLIO( :idArea ) from dual - 也许是因为uniqueResult()?尝试使用 query = " { ? = CALL GENERA_FOLIO( :idArea ) } 和 query.getResultList() 代替。见stackoverflow.com/a/14722588/1375470
  • @SeanMickey 这只是我的 oracle 服务器上的函数定义,而不是我调用它的方式。
  • @Timekiller 是的!确切地说,这就是错误,我想,我也尝试过,让我编辑问题来告诉你会发生什么

标签: java oracle hibernate


【解决方案1】:

通过将此 PRAGMA 添加到 Oracle 函数来避免 ORA-14551 错误:

pragma autonomous_transaction;

最好通过修改 Hibernate/Java 以在不同的上下文中调用该函数来解决此问题,但我不知道该怎么做。

【讨论】:

  • 老兄!有效!必须将查询更改为“从双重选择 GENERA_FOLIO(:idArea)”,并在函数的末尾提交一个 COMMIT,但它起作用了!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 2014-04-14
  • 2014-12-28
  • 1970-01-01
相关资源
最近更新 更多