从Oracle Policy

时间:2016-10-05 16:45:35

标签: oracle

我有一个Oracle策略,有一点我想停止处理并向Oracle JDBC支持的Hibernate返回一个有意义的错误。

在我的政策中,当发现某个错误时,我会执行以下操作:

RAISE_APPLICATION_ERROR( -20001, 'Unauthorized' );

注意消息可以是任何内容,这只是一个例子。

这样就可以了,策略会停止执行,同时还会调用SQL调用并返回调用函数(IE Hibernate)。

在JDBC驱动程序中,虽然我的代码和错误已从异常信息中删除:

  

]] ServletException的根本原因。   org.hibernate.exception.GenericJDBCException:无法解压缩   ResultSet at   org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)     在   org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)     在   org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)     在   org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)     在org.hibernate.loader.Loader.getResultSet(Loader.java:2066)     截断。请参阅日志文件以获取完整的堆栈跟踪引起的:   java.sql.SQLException:ORA-28112:无法执行策略函数

     

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)at at   oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)at at   oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)at at   oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)at at   oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)截断。看到   完整堆栈跟踪的日志文件

深入探讨JDBC驱动程序我的-20001错误和单词" Unauthorized"不再被人看见。有没有办法向调用程序返回有意义的错误?或者,似乎是"策略编组",将所有异常并重新包装成另一个错误?

这是向调用程序返回正确失败的最佳方法,还是有更好的方法?

我不想返回任何结果,因为这意味着一切正常,我想要返回正确的错误。

更新 使用来自@ a1ex07的异常捕获器,我发现错误确实已经消失,并且所有存在一个"进程策略"错误的地方。确切的堆栈跟踪如下:

  

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)at at   oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)at at   oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)at at   oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)at at   oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)at at   oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)at at   oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)     在   oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)     在   oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)     在   oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)     在   oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)     在   oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)     在   oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:4845)     在   oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1501)     在   weblogic.jdbc.wrapper.PreparedStatement.executeQuery(PreparedStatement.java:144)     在   org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)

此时:

  

oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)

仍然没有我的-20001或文字的迹象。看起来驱动程序会完全删除我的异常并用它自己的平淡替换它。

更新 调用Hibernate代码如下:

public List<Tag> findBy(Long termId, String tagName) {
    try {
       Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Tag.class)
            .createAlias("tagTerms", "tagTerms");
        if (tagName != null) {
          criteria.add(Restrictions.eq("tagName", tagName));
       }
       //termId not used yet        
       criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
       return criteria.list();
    } catch (RuntimeException re) {
        //SQL error is from the oracle policy and not anything else.
        log.error("get failed ", re);
        throw re;
    }
}

标签是标准的Hibernate实体。

我目前还原为使用空结果集至少不会导致一般SQL错误。我感觉这是不可能的,因为错误只是没有传回给调用程序。

希望社区能在这里提供帮助。

1 个答案:

答案 0 :(得分:0)

我认为问题不在于Oracle,而在于如何从Hibernate抛出的异常中检索错误代码。 exception.getCause()exception.getCause().getCause()应包含RAISE_APPLICATION_ERROR的错误代码。例如,您的异常处理程序(Java示例)可能看起来像

public void handleSQLException(Exception e) throws ECustomException
    {
        SQLException se = null;

        if (null != e.getCause() )
        {
            if (e.getCause() instanceof SQLException )
            {
                se = (SQLException)e.getCause();
            }
            if (null != e.getCause().getCause() && e.getCause().getCause() instanceof SQLException )
            {
                se = (SQLException)e.getCause().getCause();
            }
        }
        if (null != se)
        {

            int eCode = se.getErrorCode();
            if (eCode >0)
            {
                eCode = -eCode;
            }
            switch (eCode)
            {
                case -20001 : 
                    throw new EInvalidPolicy(se);
                --handling other defined other error codes 
                default :
                throw new RuntimeException(e);
            }
        }
        else
        {
            throw  new RuntimeException(e);
        }
    }