在 JBoss AS 7 中捕获 PersistenceException 或 ConstraintViolationException
我正处于从 JBoss AS 6 到 JBoss AS 7 的迁移过程中,但我的测试遇到了问题。让我们假设一个简单的实体 EJB:
@Entity public class MyTest implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@NotNull
private String headline;
} //getter/setter
在我的 @Stateless Bean
中,我正在做类似的事情(就像之前使用 JBoss5 和 JBoss6 一样):
@Inject private EntityManager em;
public <T extends Object> T persist(T o) throws MyContraintViolationException
{
System.out.println("***************** persist:");
try
{
em.persist(o);
}
catch (Exception e)
{
System.out.println("*************** exception:");
// Further investigation of Exception e,
// then throw MyContraintViolationException
}
}
如果我不违反 @NotNull ,这就可以正常工作约束。如果
headline==null
,我会收到异常,但不进入我的 catch
块:
12:19:45 INFO ******************** persist:
12:19:45 WARN [com.arjuna.ats.arjuna] (management-handler-threads - 2)
ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for
SynchronizationImple< 0:ffffc0a801fb:4f969a6e:4f058744:9,
org.hibernate.engine.transaction.synchronization.internal.
RegisteredSynchronization@38eb9b73 >: javax.persistence.PersistenceException:
error during managed flush
...
Caused by: javax.validation.ConstraintViolationException: Validation failed for
classes [my.test.MyTest] during persist time for groups
[javax.validation.groups.Default, ] List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='kann nicht null sein',
propertyPath=headline, rootBeanClass=class my.test.MyTest,
messageTemplate='{javax.validation.constraints.NotNull.message}'}
我很高兴看到错误消息比以前版本的 JBoss 详细得多,但我如何捕获 javax.validation.ConstraintViolationException 并抛出我自己的 MyContraintViolationException?甚至连调试消息*****异常
也没有被打印出来。
I'm in the migration process from JBoss AS 6 to JBoss AS 7 and have trouble with my tests. Let's assume a simple entity EJB:
@Entity public class MyTest implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@NotNull
private String headline;
} //getter/setter
In my @Stateless Bean
I'm doing something like this (like before with JBoss5 and JBoss6):
@Inject private EntityManager em;
public <T extends Object> T persist(T o) throws MyContraintViolationException
{
System.out.println("***************** persist:");
try
{
em.persist(o);
}
catch (Exception e)
{
System.out.println("*************** exception:");
// Further investigation of Exception e,
// then throw MyContraintViolationException
}
}
This works fine if I don't violate the @NotNull
constraint. If headline==null
, I get exceptions, but don't enter my catch
block:
12:19:45 INFO ******************** persist:
12:19:45 WARN [com.arjuna.ats.arjuna] (management-handler-threads - 2)
ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for
SynchronizationImple< 0:ffffc0a801fb:4f969a6e:4f058744:9,
org.hibernate.engine.transaction.synchronization.internal.
RegisteredSynchronization@38eb9b73 >: javax.persistence.PersistenceException:
error during managed flush
...
Caused by: javax.validation.ConstraintViolationException: Validation failed for
classes [my.test.MyTest] during persist time for groups
[javax.validation.groups.Default, ] List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='kann nicht null sein',
propertyPath=headline, rootBeanClass=class my.test.MyTest,
messageTemplate='{javax.validation.constraints.NotNull.message}'}
I'm happy to see that the error message is much more detailed than in previous versions of JBoss, but how can I catch a javax.validation.ConstraintViolationException
and throw my own MyContraintViolationException
? Even the debug message ***** exception
is not printed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在使用 EJB 来包含您的entityManager。对无状态 EJB 的每个方法调用都包装在事务中。
您已注入 EntityManager。这意味着 EntityManager 也将成为您事务的一部分。 EntityManager 仅在事务提交期间刷新,这就是您不会看到此错误消息的原因。
您应该执行以下操作:
You are using an EJB to contain your entityManager. Every method call to a Stateless EJB is wrapped in a transaction.
You have injected the EntityManager. This means that the EntityManager will be part of your transaction as well. The entityManager is only flushed during transaction commit, which is why you will not be seeing this error message.
What you should do is the following:
如果您阅读消息和异常的堆栈跟踪,您将看到此异常不是由调用 persist 引发的,而是由刷新引发的:
持久期间发生错误不会发出任何查询,也不会将任何内容保存到数据库。它只是要求实体管理器使临时实体持久化。在刷新时(即在事务提交之前,或者在 Hibernate 执行可能需要该实体位于数据库中才能返回正确结果的查询之前,或者显式调用
flush()
时) ,然后检查约束并执行插入查询。您可以显式调用刷新,但它会因为不允许 Hibernate 批处理多个查询并仅在必要时执行它们而影响应用程序的性能。我只会使用本机异常。为什么需要这样的转换?
If you read the message and the stack trace of the exception, you'll see that this exception is not thrown by the call to persist, but by the flush:
persist doesn't issue any query and doesn't save anything to database. It just asks the entity manager to make a transient entity persistent. At flush time (i.e. just before the commit of the transaction, or before Hibernate executes a query which might need this entity to be in database to return the correct results, or when
flush()
is explicitely called), then the constraints are checked and the insert query is executed.You might call flush explicitely, but it would affect the performance of the application by not letting Hibernate to batch multiple queries and execute them only when necessary. I would just use the native exception. Why do you need such a conversion?