我在使用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但它从未捕获到......例外是事务处理。
如果发现异常,为什么我仍然会在日志中看到它?
答案 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
的更多详情