2011-10-03 96 views
14

我堅持實體時使用了EJB3/JPA,我很高興看到它如何能夠管理我的數據庫相關的 任務。 我唯一關心的是異常處理。我在保存實體時的示例代碼總是出現在這種風格中。 我在網上閱讀的大多數教程都帶有這種風格,也不考慮異常處理。JPA中更好的異常處理

@Stateless 
public class StudentFacade{ 
    @PersistenceContext(unitName = "MyDBPU") 
    private EntityManager em; 

    public void save(Student student) { 
     em.persist(student); 
    } 
} 

但我不知道什麼是EJB應用程序中異常處理的最佳方式? 什麼應該是處理異常的最佳方式?

這是別人如何處理異常?會話外觀上的try catch塊?

@Stateless 
public class StudentFacade{ 
    @PersistenceContext(unitName = "MyDBPU") 
    private EntityManager em; 

    public void save(Student student) { 
     try { 
      em.persist(student); 
     } catch(Exception e) { 
      //log it or do something 
     } 
    } 
} 

或讓方法拋出一個異常?

public void save(Student student) throws Exception { 
    em.persist(student); 
} 

我不知道我的理解是否正確,因爲我還在學習EJB。 謝謝

+0

如果你拋出異常,你並不需要抓住它 –

回答

10

異常處理的想法是在發生任何故障的情況下在一個點上執行一些邏輯。 的嘗試捕捉將在您需要處理異常的最後一點被使用或者你需要一個異常轉換成另一種異常

假設你的應用程序有許多層,即行動,門面,堅持

代表例外 在這種情況下,在Facade上引發的任何異常都可以引發到上述動作層。 在操作中,特定的異常將被捕獲並處理,並顯示正確的錯誤消息。

//This is in Facade Layer 
public void save(Student student) throws AppException{ 
    //exceptions delegated to action layer 

    //call to Persist Layer 
} 

轉換期一般例外到App例外 說,在持久性你和DBException如SQLException。此異常不應該被髮送這樣行動或立面層,所以我們捕捉到的特定異常,然後拋出一個新的異常(應用程序的用戶定義的異常)

//This is in Persist Layer 
public void save(Student student) throws AppException{ 
     //converting general exception to AppException and delegating to Facade Layer 

     try{ 
      em.persist(student);//call to DB. This is in Persist Layer 
     }catch(Exception e){ 
      throw new AppException("DB exception", e) 
     } 
    } 

在操作層 你會趕上你的異常在行動,然後處理異常

//This is in Action layer 
    public void callSave(Student student){ 
      try{ 
       //call Facade layer 
      }catch(AppException e){ 
       //Log error and handle 
      } 
    } 
+3

如果持久層是一個EJB,那麼你的方法不起作用,因爲在方法返回後提交時會發生許多異常。 – Lii

3

如果你想讓你的方法拋出從em.persistance得到的異常(...),那麼不要用該try/catch塊包圍該語句(因爲它會捕獲該塊中的每個異常)。

解決這個問題的方式取決於應用程序,是否已經存在一些遺留代碼。在存在遺留代碼的情況下,我建議您使用相同的方法(即使在某些情況下,它不是速度最優的)以保持一致性。

否則,我會建議遵循例外的「經驗法則」 - 他們應該首先對待你的所有信息,你需要他們採取行動,否則扔他們,讓其他人可以處理。 (如果你把它們扔掉,一定要拋出你可能拋出的最具體的異常形式(不是一般的異常))。在使用JPA時處理異常與一般處理Java異常沒什麼兩樣。

我希望這是足夠簡單的關於異常的信息,而不必開始「宗教對話」。

0

如果你的組合是jpa的ejb,那麼所有jpa異常都是運行時異常。

EJB處理兩種類型的異常1)應用程序異常2)系統異常

應用程序異常檢查的異常基本上我們正在使用業務驗證和業務規則。

系統異常是運行時異常,所以如果任何運行時的excpetion happend ejb容器會干擾並將運行時異常轉換爲遠程異常。

對於前: 在DAO層

public void store(Cargo cargo) { 
    entityManager.persist(cargo); 
} 

所有JPA例外僅運行時異常。

在EJB服務層

public TrackingId bookNewCargo(UnLocode originUnLocode, 
     UnLocode destinationUnLocode, 
     Date arrivalDeadline) { 

    Cargo cargo = new Cargo(trackingId, routeSpecification); 
    cargoRepository.store(cargo); 
    return cargo.getTrackingId(); 
} 
在如果任何運行時異常happend,EJB容器將干擾和轉換成遠程異常EJB層

在接口層:

使這樣的JPA - > EJB - >接口