Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch PersistenceException or ConstraintViolationException in JBoss AS 7

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.

like image 636
Thor Avatar asked Dec 17 '22 05:12

Thor


1 Answers

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:

error during managed 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?

like image 108
JB Nizet Avatar answered Apr 06 '23 23:04

JB Nizet