如何让 Spring JPA、Hibernate 和 OSGi 发挥出色?

Posted

技术标签:

【中文标题】如何让 Spring JPA、Hibernate 和 OSGi 发挥出色?【英文标题】:How to Get Spring JPA, Hibernate, and OSGi to Play Nice? 【发布时间】:2011-07-17 01:20:00 【问题描述】:

我正在尝试让 WAR 文件在 Karaf OSGi 容器中运行。应用程序在独立的 Jetty 6.1.26 中正常运行,但是当应用程序在 Karaf 内部运行时,我得到以下异常并且 Karaf 实例冻结:

WARN  org.hibernate.ejb.packaging.InputStreamZippedJarVisitor - Unable to find 
file (ignored): bundle://125.0:240/ java.lang.NullPointerException: in is null

请注意,应用程序不依赖于单独的 OSGi 包中的 Hibernate;它包括 WEB-INF/lib 中的休眠 jars。

我查看了这篇帖子的信息:Equinox (OSGi) and JPA/Hibernate - Finding Entities。但是,应用程序使用的是 JPA,而不是直接使用 Hibernate。应用程序的配置很像这篇文章中的第二个选项:Difference between configuring data source in persistence.xml and in spring configuration files。因此,我没有允许我设置 annotatedClasses 属性的 Hibernate SessionFactory 的句柄。

关于如何克服异常有什么想法吗?

【问题讨论】:

【参考方案1】:

我与作者并行工作,我将在此处发布我们的解决方案,以供将来遇到此问题的任何人使用。

抛出异常是因为 Hibernate 尝试解压缩它的 jar 以查找持久性类。正如其他帖子所提到的,OSGi 不允许 Hibernate 像类加载器一样工作,所以这失败了。解决方案是指定它需要手动加载的所有类,然后告诉它不要尝试加载其他任何内容。

我们使用了persistence.xml 文件和orm.xml 文件(我们使用默认名称,因此我们不必在applicationContext.xml 中指定任何一个)。

我们的persistence.xml 文件只是使用<mapping-file> 标记指向orm.xml。它还包含<exclude-unlisted-classes/> 标记以防止休眠尝试加载其他类。

我们的orm.xml 文件使用<entity class="path.to.my.class" metadata-complete="false"/> 调用我们需要加载的每个实体类。 metadata-complete 部分告诉 hibernate 使用在类中找到的注解来完成配置。

【讨论】:

有关 Spring JPA persistence.xml 文件的示例,请参阅 Section 12.6.1.3 of the Spring Framework Reference Manual。对于此解决方案,orm.xml 文件仅包含 <entity-mappings> 元素和嵌套的 <entity> 元素每个包含 @Entity 注释的类的完全限定类名。 metadata-complete="false" 属性告诉 hibernate 从类 iteself 中指定的注解中读取所有未在 orm.xml 文件中指定的数据(在本例中为所有数据)。

以上是关于如何让 Spring JPA、Hibernate 和 OSGi 发挥出色?的主要内容,如果未能解决你的问题,请参考以下文章

Spring、Spring Security、JPA、MySQL、Hibernate 配置

Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?

spring.jpa.hibernate.ddl-auto 属性在 Spring 中是如何工作的?

如何更新 Spring Data JPA @Modifying @Query 查询中的 JPA/Hibernate @Version 字段?

Spring + Hibernate + JPA [关闭]

如何配置 Spring 使 JPA(Hibernate)和 JDBC(JdbcTemplate 或 MyBatis)共享同一个事务