从Oracle策略返回有意义的错误

从Oracle策略返回有意义的错误,oracle,Oracle,我有一个Oracle策略,有一次我想停止处理并返回一个有意义的错误给Hibernate,由Oracle JDBC支持 在我的策略中,当看到某个错误时,我会执行以下操作: RAISE_APPLICATION_ERROR( -20001, 'Unauthorized' ); 注意,消息可以是任何内容,这只是一个示例 这很好,策略停止执行,SQL调用也停止,并返回调用函数(即Hibernate) 在JDBC驱动程序中,虽然我的代码和错误已从异常信息中删除: ]]ServletException的根本

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

在我的策略中,当看到某个错误时,我会执行以下操作:

RAISE_APPLICATION_ERROR( -20001, 'Unauthorized' );
注意,消息可以是任何内容,这只是一个示例

这很好,策略停止执行,SQL调用也停止,并返回调用函数(即Hibernate)

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

]]ServletException的根本原因。 org.hibernate.exception.genericjdbception:无法提取 结果集在 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:无法执行策略函数

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

深入研究JDBC驱动程序my-20001错误和“Unauthorized”一词已不复存在。有没有办法向调用程序返回有意义的错误?或者,似乎是“策略封送器”的程序是否会将所有异常重新包装到另一个错误中

这是向调用程序返回正确故障的最佳方法还是有更好的方法

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

更新: 使用@a1ex07中的异常捕捉器,我看到错误真的消失了,并且在它的位置上存在一个“流程策略”错误。确切的堆栈跟踪如下所示:

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;
    }
}
位于的oracle.jdbc.driver.t4cttiore.processError(t4cttiore.java:450) 位于的oracle.jdbc.driver.t4cttiore.processError(t4cttiore.java:399) 位于的oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059) oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)位于 oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)位于 位于的oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587) oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225) 在 oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53) 在 oracle.jdbc.driver.T4CPreparedStatement.executeforderdescripe(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) 在 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.t4cttiore.processError(t4cttiore.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;
    }
}
public List findBy(长期ID,字符串标记名){
试一试{
Criteria=sessionFactory.getCurrentSession().createCriteria(Tag.class)
.createAlias(“标记语”、“标记语”);
if(标记名!=null){
criteria.add(Restrictions.eq(“标记名”,tagName));
}
//termId尚未使用
criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u实体)
返回条件。list();
}捕获(运行时异常re){
//SQL错误来自oracle策略,而不是其他任何原因。
log.error(“获取失败”,re);
投掷re;
}
}
标记是标准的Hibernate实体

我目前已恢复使用空结果集,至少不会导致常规SQL错误。我觉得这是不可能的,因为错误不会被传输回调用过程


希望社区能提供帮助。

我认为问题不在于Oracle,而在于如何从Hibernate引发的异常中检索错误代码
exception.getCause()
exception.getCause().getCause()
应包含来自
RAISE\u APPLICATION\u 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);
        }
    }

在我看来,问题不在于Oracle,而在于如何从Hibernate引发的异常中检索错误代码
exception.getCause()
exception.getCause().getCause()
应包含来自
RAISE\u APPLICATION\u 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);
        }
    }

请参阅我的进一步解释,虽然您的代码帮助我检查,但似乎错误已经消失。我将查看是否有任何其他方法可以从策略中返回此错误以外的内容,但是这种方法似乎根本没有机会。您可以添加调用Oracle sta的代码吗