我抓住了异常,但仍然看到它被抛入日志中

时间:2016-03-24 14:02:25

标签: java jpa exception exception-handling

我在使用JPA的Weblogic中有一个应用程序。有时当我将对象合并到DB时,我得到一个SQLIntegrityConstraintViolationException。我抓住了那个异常并处理它。问题是我仍然在日志中看到异常,即使它已被捕获和处理。一些代码:

public class MyClass implements MessageListener {
 public void onMessage(Message message) {
    //do stuff
    SomeItem someItem = processItem(request);
    localEJB.mergeAnotherItem(someItem);

}
private SomeItem processItem(ItemType item) throws Exception {            
        int retry = 0;
            boolean success = false;
            while ((!success) && (retry <= 3)) {
                try {

                    Item dbItem =  myEJB.mergeItem(item); //this causes exception
                    item = dbItem;
                    success = true;
                } catch (TransactionRolledbackLocalException ex) {
                    retry++;
                    if (ex.getCause().toString().contains("SQLIntegrityConstraintViolationException")) {
                    logger.log("TransactionRolledbackLocalException SQLIntegrityConstraintViolationException while merging on try # " + retry);
                        Item dbItem2 = myEJB.findItem(itemName);
                        if dbItem2 != null) {
                            item= dbItem2 ;
                        }
                        if (retry > 3) {
                            //log
                        }
                    } 
                }catch(Exception ex){
                        //log cause, etc
                    }
    }   

}

我的EJB代码,我从

调用方法
@Stateless(name = "MyEJB", mappedName = "MyService-MySessionEJB")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyEJBBean implements MyEJBSessionEJB,
                                                        MySessionEJBLocal {
    @PersistenceContext(unitName="MyModel")
    private EntityManager em;


    public Item mergeItem(Item item) {
        return em.merge(item); //This throws the SQLIntegrityConstraintViolationException, an internal exception wrapped in TransactionRolledbackLocalException. Which I'm catching in the caller
    }


     /** <code>select o from Items o where o.itemName = :itemName</code> */
         public Item findItem(String itemName) {
             try {
                 return (Item)em.createNamedQuery("Item.findByName").setParameter("itemName", itemName).getSingleResult();
             } catch (NoResultException e) {
                 return null;
             }
         }


}

在日志中我看到mergeItem有时会失败。然后重试它。它在第一次重试后工作。但是在日志中我看到失败的三个条目

警告:

    UnitOfWork(738260825)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (ITEM1_UK) violated

错误:

    Exception occurred during commit of transaction Name=[EJB MyEJB.mergeItem(Item)],Xid=BEA1-29FF28139113B72A3D9D(738260452),Status=Rolled back. [Reason=Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (ITEM1_UK) violated

然后我捕获异常时的日志条目

TransactionRolledbackLocalException SQLIntegrityConstraintViolationException while merging on try # 1

我清楚地捕获了异常,但同时我仍然在日志中看到异常。 我尝试捕获异常e但它从未捕获到......例外是事务处理。

如果发现异常,为什么我仍然会在日志中看到它?

1 个答案:

答案 0 :(得分:2)

EclipseLink具有用于记录异常的特殊属性eclipselink.logging.exceptions

  

使用eclipselink.logging.exceptions指定在将异常返回给调用应用程序之前是否在抛出异常时记录异常。 - 请参阅:http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_logging_exceptions.htm

它的默认值为true。所以你只需要将属性值设置为false。
例如在persistence.xml中

<property name="eclipselink.logging.exceptions" value="false" />

<强>更新

事实证明,EclipseLink文档给出了eclipselink.logging.exceptions属性的混乱描述。

属性值设置为shouldLogExceptionStackTrace记录器标志

String exString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_EXCEPTIONS, m, session);
if (exString != null) {
    log.setShouldLogExceptionStackTrace(Boolean.parseBoolean(exString));
}

shouldLogExceptionStackTrace标志的名称表示它是关于记录堆栈跟踪而不是关于异常本身。它按以下方式使用:

if (shouldLogExceptionStackTrace()) {
    entry.getException().printStackTrace(new PrintWriter(getWriter()));
} else {
    writeMessage(entry.getException().toString());
}

我已检查过其他日志记录参数,看起来从日志中删除EclipseLink异常的唯一方法是使用适当的日志记录级别或禁用日志记录

<property name="eclipselink.logging.level" value="OFF"/>

查看有关EclipsLink wiki How To Configure Logging

的更多详情