如何让 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 使 JPA(Hibernate)和 JDBC(JdbcTemplate 或 MyBatis)共享同一个事务