Поймать исключение PersistenceException или ConstraintViolationException в JBoss AS 7 - PullRequest
4 голосов
/ 05 января 2012

Я нахожусь в процессе миграции с 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?Даже отладочное сообщение ***** exception печатается , а не .

Ответы [ 2 ]

11 голосов
/ 15 января 2012

Если вы прочитаете сообщение и трассировку стека исключения, вы увидите, что это исключение вызывается не вызовом persist, а ошибкой сброса:

во время управляемого сброса

persist не выдает никаких запросов и ничего не сохраняет в базу данных.Он просто просит менеджера сущностей сделать временную сущность постоянной.Во время сброса (т. Е. Непосредственно перед фиксацией транзакции или перед тем, как Hibernate выполнит запрос, который может потребовать, чтобы этот объект находился в базе данных для возврата правильных результатов, или когда явно вызывается flush()), тогда проверяются ограничения изапрос на вставку выполняется.

Вы можете явно вызвать flush, но это повлияет на производительность приложения, не позволяя Hibernate пакетировать несколько запросов и выполнять их только при необходимости.Я бы просто использовал нативное исключение.Зачем вам нужно такое преобразование?

0 голосов
/ 19 января 2012

Вы используете EJB для хранения вашего entityManager.Каждый вызов метода для EJB без сохранения состояния заключен в транзакцию.

Вы ввели EntityManager.Это означает, что EntityManager также будет частью вашей транзакции.EntityManager сбрасывается только во время фиксации транзакции, поэтому вы не увидите это сообщение об ошибке.

Вам нужно сделать следующее:

@Inject private EntityManager em;

public <T extends Object> T persist(T o) throws MyContraintViolationException
{
System.out.println("***************** persist:");
em.persist(o);
try
{
   em.flush();
}
catch (Exception e)
{
  System.out.println("*************** exception:");
  // Further investigation of Exception e,
  // then throw MyContraintViolationException
}
}
...