如何从InvocationTargetException获取sql异常

时间:2013-06-24 15:21:29

标签: java jpa reflection exception-handling

我们正在使用Apache的openJPA。我使用Java反射在托管bean中调用delete方法。当我尝试删除由于约束违规而无法删除的manged对象时,会发生此问题。当我捕获InvocationTargetException并检索异常的原因时,它指出没有全局事务存在要回滚。

Caused by: java.lang.IllegalStateException: No Global Transaction exists to rollback.
    at com.ibm.ws.tx.jta.UserTransactionImpl.rollback(UserTransactionImpl.java:349)

如果我在堆栈跟踪中看得更远,我可以看到由于违反约束而抛出了SQL异常。

---- Begin backtrace for Nested Throwables
java.sql.SQLException: [SQL0532] Delete prevented by referential constraint CONSTRAINTNAME in LIBRARY.

有没有办法让我得到SQL异常,所以我可以显示一条友好的消息,表示删除无法执行,因为它正在另一个表中使用。

编辑 - 这是代码

public void deleteRowAction(Object list, DataTableTemplate template){
        System.out.println("Delete Row");

        try{

            Object bean = getManagedBean(template.getDataManagerName());

            Method methodDelete = getManagedBean(template.getDataManagerName()).getClass().getMethod(template.getDeleteMethod(), 
                    Class.forName(template.getTableList_rowItemClassName()));

            //Map<String, String[]> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap();

            methodDelete.invoke(bean, list);
        }
        catch(PersistenceException pe){
            System.out.println("Persistence Exception Caught");
        }
        catch(NoSuchMethodException nsme){
            nsme.printStackTrace();
        }
        catch(InvocationTargetException ite){

            logException(ite);
            FacesMessage message = new FacesMessage(ite.getCause().getMessage());
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            FacesContext context = this.getFacesContext();
            context.addMessage(null, message);
        }
        catch(IllegalAccessException iae){
            iae.printStackTrace();
        }
        catch(ClassNotFoundException cnfe){
            cnfe.printStackTrace();
        }
    }

2 个答案:

答案 0 :(得分:0)

将您的异常传递给下面的方法,递归检索SQLException

    try{
        ....
    } catch(PersistenceException pe){
        SQLException sqle = translate(pe);
    } catch(NoSuchMethodException nsme){
        SQLException sqle = translate(nsme);
    }
    ...

public SQLException translate(RuntimeException e) {
    SQLException result = null;
    Throwable throwable = e;
    while (throwable != null && !(throwable instanceof SQLException)) {
        throwable = throwable.getCause();
    }
    if (throwable instanceof SQLException) {
        System.out.println("Found SQLException...")
        result = (SQLException) throwable;
    }
    return result;
} 

答案 1 :(得分:0)

我们正在使用IBM的Websphere。以下代码由Websphere自动生成。由于数据约束没有发生删除,因此回滚失败。这会导致回滚抛出异常,从而导致原始异常丢失。如果我想看到Constraint异常(我们不能这样做),我将不得不修改此方法。我们将改为记录一般错误消息。

 @Action(Action.ACTION_TYPE.DELETE)
 public String deleteVerificationDocumentCodeTable(
                VerificationDocumentCodeTable verificationDocumentCodeTable)
                throws Exception {
    EntityManager em = getEntityManager();
                try {
                    utx.begin();
                    em.joinTransaction();
                    verificationDocumentCodeTable = em
                            .merge(verificationDocumentCodeTable);
                    em.remove(verificationDocumentCodeTable);
                    utx.commit();
                } catch (Exception ex) {
                    try {
                        utx.rollback();
                    } catch (Exception e) {
                        ex.printStackTrace();
                        throw e;
                    }
                    throw ex;
                } finally {
                    em.close();
                }
                return "";
}