0

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

因此,据我所见,我有以下项目可能会或可能不会从某些正在运行的代码中看到,我们称它们为“主题”:

  • JPA 注释实体类
  • 一种persistence.xml
  • 持久性 APIjavax.persistence
  • 持久性提供者类

我的代码中有以下情况:

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

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

我想这可能很明显

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

1 回答 1

1

创建这些包:

  • 模型(您的 JPA 注释类)
  • 库(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 与来自 B 的 X 不同。每个X 与外界完全封装。

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

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

于 2009-10-13T15:15:20.190 回答