0

我使用 Spring 和 JPA (EclispeLink) 开发 Java EE 应用程序。我们开发了一个用户友好的界面来管理数据库表。随着我现在对 Spring 和 Transactions 有了更多的了解,我决定重构我的代码以添加更好的事务管理。问题是如何最好地处理通用 DAO、通用服务和 Spring 事务?

我们目前的解决方案是:

  • 处理所有常见数据库操作(查找、创建、更新、删除...)的通用 BasicDAO
  • 一个 DaoFactory,其中包含所有实体类型的 BasicDao 实现映射(只需要基本的数据库操作),并获取 spring 注入的 entitymanager 以将其传递给 daos
  • 提供通用服务的通用 BasicService(实际上直接链接到 dao 方法)
  • 一个 ServiceFactory,其中包含所有实体类型的 BasicService 实现映射,它获取 daoFactory 注入并将其传递给服务。它有一个方法“getService(Class T)”来为控制器提供正确的服务。
  • 对应于正确实体类型的控制器将其请求委托给通用控制器,该控制器使用反射处理请求参数并从服务工厂的映射中检索正确的服务以调用更新/创建/删除方法。

问题是,当我在通用服务上添加 @Transactionnal 注释并且我的 serviceFactory 在其映射中创建类型化服务时,这些服务似乎没有正在运行的活动事务。

1)由于通用性和只有spring管理的服务可以进行事务,这是否正常?

2)解决我的问题的最佳解决方案是什么:

  • 创建仅实现通用服务的托管类型服务并将它们直接注入我的 serviceFactory?
  • 去掉这些基础服务的服务层?(但也许我的 dao 通用层上的事务也会遇到同样的问题......)
  • 其他建议?

我在网上阅读了一些与这些观点相关的问题,但找不到像这里一样具有通用性的例子,所以我希望有人能给我建议......提前致谢!

4

1 回答 1

1

对于基本获取,您不需要服务层。

服务层用于处理多个聚合根——即涉及多个不同实体的复杂逻辑。

我的通用存储库实现如下所示:

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 ..

由 spring 实例化的不同类型:

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

并且可以像这样引用:

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

并且也可以为复杂实体手动扩展。

于 2013-06-12T12:48:32.427 回答