2013-06-12 34 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; 

而且也可以针对复杂实体进行手动扩展。