Java EJB3获取原始JDBC错误
我使用默认的TopLink持久性管理器在Glassfish上使用EJB3。在会话Bean中,当持久性管理器捕获到一个DB异常时,它会标记要回滚的事务,并抛出一个EJBException,然后包装一个回滚异常。现在我希望能够从其中一个异常的由异常引起的异常中获取原始jdbc异常,但事实并非如此 检索原始异常非常重要,因为我需要向用户报告问题所在,为此我需要分析SQL错误代码 有人知道是否有可能从Toplink获得此信息吗?或者冬眠是否使之成为可能 谢谢,好问题,Ant 我知道您想抛出数据库异常,但当它发生时,应用程序在大多数情况下无法恢复其初始状态,或者不知道如何从中恢复。因此,它应该作为运行时异常处理。数据库异常中的一些问题包括Java EJB3获取原始JDBC错误,java,hibernate,glassfish,ejb-3.0,toplink,Java,Hibernate,Glassfish,Ejb 3.0,Toplink,我使用默认的TopLink持久性管理器在Glassfish上使用EJB3。在会话Bean中,当持久性管理器捕获到一个DB异常时,它会标记要回滚的事务,并抛出一个EJBException,然后包装一个回滚异常。现在我希望能够从其中一个异常的由异常引起的异常中获取原始jdbc异常,但事实并非如此 检索原始异常非常重要,因为我需要向用户报告问题所在,为此我需要分析SQL错误代码 有人知道是否有可能从Toplink获得此信息吗?或者冬眠是否使之成为可能 谢谢,好问题,Ant 我知道您想抛出数据库异常,但
- 数据库连接失败
- 这个疑问是错误的
- 表或列不存在
- 使用业务委托模式访问EJB
@Stateless
public class BeanImpl implements Bean {
public void doSomething() {
try {
// some code
} catch(SomeException e) {
throw new EJBException(e);
}
}
}
因此,您可以通过业务代理包装会话bean
public class BeamBusinessDelegate implements Bean {
// your stateless session bean goes here
private Bean bean;
public BeamImpl() {
InitialContext i = new InitialContext();
bean = (Bean) i.lookup(<GLOBAL_JNDI_ADDRESS_OR_RELATIVE_ENVIRONMENT_NAMING_CONTEXT_ADDRESS>);
}
public void doSomething() {
try {
bean.doSomething()
} catch(EJBException e) {
throw e.getCause();
}
}
}
所以在你的商业方法中
@Stateless
public class BeanImpl implements Bean {
public void doSomething() {
try {
// some code
} catch(SomeException e) {
throw new DatabaseException();
}
}
}
关于,我也有同样的问题。我最终使用了AroundInvoke拦截器方法,这样您就可以在服务器端捕获任何异常,提取您想要的任何信息,并将其包装为抛出您自己的异常,并设置EjbContext以回滚事务
如果你做得不对,我可以给你举个例子。我发现要做我想做的事情,唯一的方法是强制管理器使用manager.flush()向db写入,然后捕获引发的PersistenceException。然后,我可以根据需要记录数据库错误,并抛出EJBException以强制回滚。离开容器进行刷新似乎无法挽回地丢失了TopLink的任何有用消息。我有同样的问题:如何获取从JPA生成的SQL错误消息 我也没有找到解决方案,但是,我在persistence.xml中添加了这一行
<properties>
<property name="toplink.logging.level" value="FINE" />
</properties>
现在,我可以看到发出的sql命令
参考:
您好-谢谢您的回复。你的例子非常准确地说明了我们已经在做什么。我想你误解了我的问题。问题在于,默认的持久性管理器Toplink在EJBException的“原因”字段中不包含原始原因。所以我的问题是,有没有办法让Toplink正确地包含原因,或者Hibernate做得更好呢?哦-而且看起来还不清楚引发异常的不是我的代码-我们正在使用实体bean来持久化数据,持久性管理器抛出EJBException,该EJBException封装了一个RolledbackException,该异常没有其原因集。我认为您无法访问底层JBDC层。在看到PersistenceException——Java Persisntece API的根异常之后,它并没有为您提供访问底层JDBC层的方法,所以我认为这是不可能的。感谢Arthur-ChristiaanP有一个看起来很有希望的线索,我将在上面尝试。我不敢相信没有办法获得这些信息,因为如果您想成功地处理或报告持久化或合并中的错误,SQL错误代码是必不可少的。我以前没有遇到过拦截器,但只是对它们进行了一些阅读,这看起来正是我想要的。然而,看起来我可以为业务方法和生命周期事件定义拦截器,但这两个似乎都不是我想要的,因为我想要拦截的方法在EntityManager中。我们将非常感激地接受更多的建议!我有同样的问题,你能用代码样本编辑你的答案吗?
<properties>
<property name="toplink.logging.level" value="FINE" />
</properties>