【问题标题】:Who needs to see who in a JPA application?谁需要在 JPA 应用程序中查看谁?
【发布时间】:2010-12-06 08:36:35
【问题描述】:

我有使用 JPA 的代码,并且在我的开发环境和单元测试中一切正常。但是将我的模块部署到 OSGi 目标环境中时,我经常遇到最奇怪的类加载问题。我真的很喜欢 OSGi,但如果我不能一劳永逸地解决这个问题,我会发疯的。只要我不明白哪些类需要被哪些其他类看到,我就永远不会正确设置 OSGi 的东西。

所以,据我所知,我有以下项目,这些项目可能从某些运行代码中可见或不可见,我们称它们为“主题”:

  • JPA 注释实体类
  • persistence.xml
  • javax.persistence 中的持久化 API
  • 持久性提供程序类

我的代码中有以下情况:

  • 创建一个EntityManagerFactory 和一个EntityManager
  • 实例化新的实体对象
  • 将这些对象传递给 EntityManager 以将它们放入其持久性上下文中
  • 继续使用它们,偶尔要求 EntityManager 保存更改
  • 实例化、使用和丢弃实体对象而不将它们保存到数据库或以其他方式显式调用 EntityManager 的方法
  • 不是实例化实体对象,而是要求 EM 从数据库中加载它们,这会导致在我看不到的地方发生实例化。
  • 使用、更改、保存和丢弃这些实例

那么,在上述哪种情况下,我需要哪些主体可见?

我想这可能很明显

  • 持久性提供程序和实体类需要了解 javax.persistence
  • 创建 EntityManager 的代码需要查看 javax.persistence(我猜是持久性提供程序,尽管这在我自己的任何代码中都没有直接可见)

【问题讨论】:

    标签: jpa visibility classloader


    【解决方案1】:

    创建这些捆绑包:

    • 模型(您的 JPA 注释类)
    • Lib (javax.persistence)
    • DAO(persistence.xml,持久性提供程序类)
    • 企业代码

    可见性:

    • 模型导入和导出库
    • DAO 导入模型(进而导入 Lib)。 DAO 导出了 EM 和 Model 的搜索方法。
    • 业务代码导入 DAO

    [编辑] 你必须了解的是 OSGi 类加载是如何工作的:如果你有两个包 A 和 B,并且你导入的两个包都在 C 中使用,那么 A 看不到 B,B 看不到 A 中的任何内容。 C 可以看到两者。

    现在 A 和 B 使用库包 X。如果 A 从 X 创建一些实例并将其传递给 C,C 再将其传递给 B,您将收到错误,因为来自 A 的 X 与来自的 X 不同B. 每一个 X 都是完全与外界隔绝的。

    在 Java 术语中:来自 X 的类是使用不同的类加载器创建的,即使名称相同,来自不同类加载器的类从不相同。

    这就是为什么您必须避免从两个不同的路径导入 X。

    【讨论】:

    • 但是Model至少不需要看Lib吗?
    • 如果我不将persistence.xml 与模型放在同一个包中,我肯定会遇到麻烦,这已经让我很痛苦了。
    • 那些后来的 cmets 非常有帮助,我并没有真正理解这一点,它会严重影响任何根据 Class 参考查找内容的东西。例如,我的持久性提供程序(eclipselink)有一个Map<Class, Something>,它用来决定它是否可以持久化一个特定的对象。看看我现在能不能掌握它。
    • 如果你把 X 当作模型,我想我不应该到处实例化它的类并将它们传递给 DAO 来持久化,因为突然之间意味着相同的类被认为是不同的, 正确的?这可以解释我的很多麻烦。
    猜你喜欢
    • 2012-06-02
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    相关资源
    最近更新 更多