谁需要在JPA应用程序中查看谁?

时间:2009-10-13 15:03:21

标签: jpa visibility classloader

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

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

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

我的代码中有以下情况:

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

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

我想这很明显

  • 持久性提供程序和实体类需要知道javax.persistence
  • 创建EntityManager的代码需要查看javax.persistence(我想是持久性提供程序,尽管在我自己的代码中没有直接显示)

1 个答案:

答案 0 :(得分:1)

创建这些包:

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

可见性:

  • 模型导入和导出Lib
  • DAO导入模型(从而导入Lib)。 DAO导出EM和模型的搜索方法。
  • 商业代码导入DAO

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

现在A和B使用一个库包X.如果A从X创建了一个实例并将其传递给C,后者又将它传递给B,你会得到错误,因为A中的X与来自的X不同B.每个X都完全封装在外面。

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

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