2012-01-05 51 views
4

我正在從JBoss AS 6遷移到JBoss AS 7,並且遇到了我的測試問題。讓我們假設一個簡單的實體EJB:JBoss AS 7中的Catch PersistenceException或ConstraintViolationException

@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. 
    [email protected] >: 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也不是已打印。

回答

11

如果你讀的消息和異常的堆棧跟蹤,你會看到這個異常沒有被調用拋出堅持,但沖洗:在

錯誤管理平齊

persist不會發出任何查詢並且不會將任何內容保存到數據庫。它只是要求實體經理持久化一個臨時實體。在刷新時(即在事務提交之前,或在Hibernate執行可能需要此實體在數據庫中以返回正確結果的查詢之前,或者在明確調用flush()時),則會檢查約束並插入查詢被執行。

您可能會明確地調用flush,但它會通過不讓Hibernate批量多個查詢並僅在必要時執行它們來影響應用程序的性能。我只會使用本機異常。你爲什麼需要這樣的轉換?

0

您正在使用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 
} 
}