【发布时间】:2012-01-03 17:03:55
【问题描述】:
我正在使用 JPA/Hibernate(他们是新手)。当发生异常时(可能是违反唯一约束),我想捕获它并显示一些应用程序含义消息,而不是打印堆栈跟踪。
Hibernate 是否提供一些工具来获取有关异常的信息(可能与数据库无关)?
【问题讨论】:
我正在使用 JPA/Hibernate(他们是新手)。当发生异常时(可能是违反唯一约束),我想捕获它并显示一些应用程序含义消息,而不是打印堆栈跟踪。
Hibernate 是否提供一些工具来获取有关异常的信息(可能与数据库无关)?
【问题讨论】:
HibernateException 封装了实际的根本原因,可以为您提供足够的信息来生成有意义的用户友好消息。阅读他们文档的Exception Handling 部分。
【讨论】:
你可以像下面这样。我这样做了。但是当然,您使用的是供应商特定的代码,因此如果您使用不同的 JPS 提供商,您将不得不在几个地方更改代码。同时,有时当您知道自己不会轻易更改 JPA 提供程序并且用户友好的错误消息更重要时,它很实用
try{
...
}
catch( javax.persistence.PersistenceException ex)
{
if(ex.getCause() instanceof org.hibernate.exception.ConstraintViolationException)
{..........}
}
【讨论】:
你也可以抓到将军JDBCException:
try {
userDao.save(user); //might throw exception
} catch(JDBCException e) {
//Error during hibernate query
}
或者您也可以捕获JDBCException 的更具体的子类之一,例如ConstraintViolationException 或JDBCConnectionException:
try {
userDao.save(user); //might throw exception
} catch(ConstraintViolationException e) {
//Email Address already exists
} catch(JDBCConnectionException e) {
//Lost the connection
}
使用e.getCause() 方法,您可以检索底层SQLException 并进一步分析:
try {
userDao.save(user); //might throw exception
} catch(JDBCException e) {
SQLException cause = (SQLException) e.getCause();
//evaluate cause and find out what was the problem
System.out.println(cause.getMessage());
}
例如会打印:Duplicate entry 'UserTestUsername' for key 'username'
【讨论】:
您可以专门捕获 org.hibernate.exception.ConstraintViolationException。这样你就知道你只发现了约束问题。
【讨论】:
当您想在 Session 上调用 Flush() 或在 Transaction 上调用 commit() 时,您可以捕获 Hibernate 异常。
try {
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("Hibernate Exception: " + e.getMessage());
}
// or
try {
session.flush();
} catch (Exception e) {
System.out.println("Hibernate Exception: " + e.getMessage());
}
【讨论】:
Hibernate 中的所有异常都是 Java 的 RuntimeException 类的派生类。因此,如果您在代码中捕获了 RuntimeException,您可以通过调用 Exception 类的 getCause() 或 getMessage() 方法来获取异常原因
【讨论】: