2013-06-12 37 views
0

我使用Spring和JPA(EclispeLink)開發Java EE應用程序。我們開發了用於管理數據庫表的用戶友好界面。由於我現在更多地瞭解Spring和Transactions,我決定重構我的代碼以添加更好的事務管理。問題是如何最好地處理通用DAO,通用服務和Spring事務?Spring事務和通用DA​​O和服務的最佳實踐

我們目前的解決方案是:

  • 的通用BasicDAO與所有常見的數據庫操作交易(查找,創建,更新,刪除...)
  • 其中包含地圖BasicDao的實現的DaoFactory對於所有實體類型(只需要基本的數據庫操作),並獲得春天注入的實體管理器將其傳遞給daos
  • 提供公共服務的通用BasicService(實際上直接鏈接到dao方法)
  • A ServiceFa ctory,其中包含所有實體類型的BasicService實現的映射,它們將daoFactory注入並將其傳遞給服務。它有一個「getService(Class T)」方法來爲控制器提供正確的服務。
  • 控制器對應於正確的實體類型,它們將請求委託給通用控制器,通用控制器使用反射來處理請求參數,並從服務工廠的映射中檢索正確的服務以調用update/create/remove方法。

問題是,當我在通用Service上添加@Transactionnal註釋並且我的serviceFactory在其映射中創建了類型化服務時,這些服務似乎沒有正在運行的活動事務。

1)這是正常的,由於通用性和事實,只有春季管理的服務可以有交易?

2)什麼是解決我的問題的最佳解決方案:

  • 創建管理類型服務僅實現通用服務,直接在我的服務工廠注入呢?
  • 刪除這些基本服務的服務層? (但也許我會得到同樣的問題與我的道通用層上的交易...)
  • 其他建議?

我在網上閱讀了一些與這些問題有關的問題,但是找不到像這裏一樣的通用性的例子,所以我希望有人能夠建議我......先謝謝了!

+0

你不能繼承註解: – NimChimpsky

+0

它實際上不是繼承...這是關於泛型類型的實例化(例如:IService projectService =新BasicService ()//該projectService無法處理它們的交易在BasicService中指定,因爲它不是一個託管實體...) – Coralie

+0

沒有實例化你的服務然後 – NimChimpsky

回答

1

對於基本而言,您不需要服務層。

服務層用於處理多個聚合根 - 即複雜的邏輯invloving多個不同的實體。

我的一個通用存儲庫的實現看起來是這樣的:

public class DomainRepository<T> { 

    @Resource(name = "sessionFactory") 
    protected SessionFactory sessionFactory; 

public DomainRepository(Class genericType) { 
     this.genericType = genericType; 
    } 

@Transactional(readOnly = true) 
    public T get(final long id) { 
     return (T) sessionFactory.getCurrentSession().get(genericType, id); 
    } 

@Transactional(readOnly = true) 
    public <T> List<T> getFieldEquals(String fieldName, Object value) { 
     final Session session = sessionFactory.getCurrentSession(); 
     final Criteria crit = session.createCriteria(genericType). 
       add(Restrictions.eq(fieldName, value)); 
     return crit.list(); 
    } 
//and so on .. 

與春天實例化不同的類型:

<bean id="tagRepository" class="com.yourcompnay.data.DomainRepository"> 
     <constructor-arg value="com.yourcompnay.domain.Tag"/> 
</bean> 

,可以像這樣被引用:

@Resource(name = "tagRepository") 
private DomainRepository<Tag> tagRepository; 

而且也可以針對複雜實體進行手動擴展。