2017-08-21 81 views
1

爲什麼JPA在我執行合併的方法中爲唯一約束違規引發異常?相反,我看到在我的代碼中拋出一個異常。JPA異常合併

我想獲取異常消息(更新錯誤),但它沒有捕獲異常。

我希望得到這樣的響應:

{ 
    "errorMessage": "Update Error", 
    "errorCode": 404, 
    "documentation": "" 
} 

相反,在控制檯中我得到這個錯誤:

Caused by: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back 
..... 
... 
Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction. 
..... 
..... 
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement 
...... 
..... 
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (DEMAND_TD_CODE) violated 
..... 
.... 

這裏是我做了更新:​​

@Override 
    public Demand updateDemand(Demand demand) throws DemandExceptions { 
     try { 
      Demand demandToUpdate = entityManager.merge(demand); 
     } catch (PersistenceException e) { 
      throw new DemandExceptions("Update Error"); 
     } 
      return demandToUpdate; 
    } 

DemandeExceptions .java

public class DemandeExceptions extends Exception implements Serializable { 
    private static final long serialVersionUID = 1L; 
    public DemandeExceptions (String message) { 
     super(message); 
    } 
} 

@Provider 
public class DemandExceptionsMapper implements ExceptionMapper<DemandeExceptions >{ 

    @Override 
    public Response toResponse(DemandeExceptions ex) { 
     ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), 404, ""); 
     return Response.status(Status.NOT_FOUND) 
       .entity(errorMessage) 
       .build(); 
    } 

} 

ErrorMessage.java

@XmlRootElement 
public class ErrorMessage { 

    private String errorMessage; 
    private int errorCode; 
    private String documentation; 
    .. 
} 
+0

'違反唯一約束(DEMAND_TD_CODE)'。所以修復爲什麼這是違反... –

+0

我在數據庫中定義它像獨特,我試圖添加一個實體witj相同的代碼進行測試 – user1814879

+0

所以這是一個測試,你只是想檢測它?所以尋找一個帶有原因異常的PersistenceException,它是SQLIntegrityConstraintViolationException –

回答

4

爲了提高性能,大多數JPA實現緩存數據庫操作,而不是在每個JPA方法調用中都擊中數據庫。這意味着當您調用merge()時,更改記錄在JPA實施管理的Java數據結構中,但數據庫中尚未發生更新。

JPA實現不檢測像唯一約束違規這樣的問題 - 這留給數據庫。

這意味着在捕獲PersistenceException的try塊內不會發生唯一約束違規。相反,當JPA決定需要將更新刷新到數據庫時引發異常。這種自動刷新通常在事務提交時發生,但可能會更快發生(例如,如果需要對更新的表執行查詢)。

您可以通過調用EntityManager.flush()手動刷新JPA狀態。如果你在try塊中這樣做,你會得到你認爲你會的PersistenceException。

try { 
     Demand demandToUpdate = entityManager.merge(demand); 
     entityManager.flush(); 
    } catch (PersistenceException e) { 
     throw new DemandExceptions("Update Error: " + e.getMessage()); 
    } 
+0

Thxxx So Muchhhh。它工作得很好.... – user1814879

0

這些都是可能導致錯誤的問題:

  • 檢查交易關閉後,你是趕上例外。
  • 檢查您是否使用了正確的類的PersistenceException(檢查包裝)其實
+0

我使用:'import javax.persistence.PersistenceContext;', – user1814879

+0

是的,你應該捕獲javax.persistence。在transaction.close()之後的PersistenceException 。 嘗試調試代碼,檢查你是否真的拋出你的自定義異常 –

0

異常不會被抓住,但你失去了原有的消息,考慮更新catch塊如下:

throw new DemandExceptions("Update Error, original message: " + e.getMessage()); 
+0

哼,是的,但我不能得到這個消息,這是我的問題 – user1814879