【问题标题】:How to best share entity classes/DAOs across multiple PUs?如何在多个 PU 之间最好地共享实体类/DAO?
【发布时间】:2013-04-10 13:17:30
【问题描述】:

让我们举一个基本的例子,假设我们有一个实体类

@Entity
public class User {
}

以及用于处理数据的 DAO:

public interface UserDao {
    @Transactional
    public void changeUser(User user);
}

@Repository
public class UserDaoImpl implements UserDao {
    @PersistenceContext
    private EntityManager em;

    @Override
    public void changeUser(User user) {
        // ...
    }
}

我们有一个主 Maven 项目,其中包含许多其他子项目,我们用于构建多个应用程序(WAR、JAR 等)。我们选择的框架是 Spring。

每个应用程序都需要上述实体/DAO,并且不需要对每个应用程序进行自定义,一切都保持不变。 每个应用程序都有自己的数据源/持久性单元/事务管理器。

如何才能在多个应用程序中最好地重用上述实体/DAO?实体需要持久保存在应用程序的数据库中,我们还需要重用应用程序的事务管理器。

你在类似的情况下做了什么?

【问题讨论】:

  • 这些应用程序的数据源是否相同?
  • @Sashi 没有。每个应用程序都有自己的数据源,背后有不同的数据库。

标签: java spring jakarta-ee jpa architecture


【解决方案1】:

我将创建包含实体和 DAO 的单独 Maven 模块(您甚至可以创建两个模块 - 一个用于实体,一个用于 DAO)。

此模块将作为依赖项添加到需要 DB 层的任何其他应用程序模块(EJB 或 WAR 模块)。在 Spring 配置中,您应该正确定义数据源、持久化上下文、事务管理器等的注入规则。这样您将拥有具有不同配置的通用代码。

【讨论】:

  • 通用实体和 DAO 已经是 maven 模块 persistence-common 的一部分。您将如何进行 Spring 配置?这似乎是有点棘手的地方。
  • persistence-common 不应该有 Spring 上下文文件,每个 EAR 或 EJB 或 WAR 模块应该有自己的带有持久性配置的上下文文件 - 数据源加事务管理器加 JPA 模板(如果你想使用它) .该文件应导入主弹簧上下文文件。显然这些模块中的每一个也需要persistence.xml文件
  • 我正在按照您建议的方式进行尝试,war 文件会正确生成,但是当我尝试启动服务器并部署项目时,我在 tomcat 日志中收到此错误:“原因: org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到符合条件的 bean [com.myproject.commons.mydao.SuperEntityDao] 类型的依赖项:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖项注释:{@org .springframework.beans.factory.annotation.Autowired(required=true)}" 关于如何解决这个问题的任何想法?
【解决方案2】:

我同意,模块化类是容易的部分;自动化配置查找/加载是棘手的部分。

我想可以为每个模块创建一个applicationContext.xml(在其中列出 bean、控制器等)并使用多重配置支持来加载它们。但显然我们不能将所有 XML 文件命名为相同,我建议如下:

主项目的web.xml:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:auto-appctx-*.xml</param-value>
    </context-param>

还有一个 Maven/Ant 脚本,它会在打包每个模块/JAR 期间为 XML 文件添加时间戳,如下所示:

    <target name="copy-unique-appctx">
        <timestamp/>
        <copy src="src/resource/applicationContext.xml"
            dest="build/classes/auto-appctx-${timestamp}.xml"/>
    </target>

请注意,这个 Ant 目标是“按记忆”键入的,目前还很粗略,需要更正(如果这个想法确实有效)。

【讨论】:

  • 其实这不是必须的。每个应用程序都有一个主 Maven 模块,因此我们为每个应用程序都有一个自定义的主资源(例如 web.xml),我们可以在其中定义加载的内容和不加载的内容。每个应用程序还有一个父上下文和一个持久性单元(META-INF/persistence.xml),也是这个主模块的一部分。遇到的第一个问题是从注册的不同模块(jar)中获取实体......这还没有结束。
  • 请检查this article 和this one。这个想法是在每个 JAR 中保留persistence.xml,但能够在应用程序中自动“找到它们”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 2017-07-08
  • 2021-07-04
  • 2021-09-14
  • 2016-11-01
  • 1970-01-01
  • 2017-06-27
相关资源
最近更新 更多