当前位置: 首页 > 知识库问答 >
问题:

对Java 9的Hibernate支持

公孙和怡
2023-03-14

Hibernate准备好与Java9的可用构建一起工作了吗?

共有1个答案

路裕
2023-03-14

我也想知道同样的事情,并尝试在早期的Java9 access版本下运行我的Hibernate应用程序。以下是我学到的。

我遇到的第一个问题是javax.xml.bind.JAXBException的ClassNotFoundException。JAXB从Java6开始就存在于运行时类路径中,但在Java9中,默认情况下不再发布它。至少有两种方法可以解决此问题:

>

  • 在Java9 JVM中运行程序时,包含命令行参数“--add-modules Java.se.ee”。这指示Java9再次在类路径中包含JAXB(和其他库)。但是请记住,这个论点将被Java8 JVM拒绝;因此,如果允许用户在多个Java版本下运行,则必须动态计算命令行,或者要求用户手动编辑命令行。
  • 在应用程序中包含JAXB库。如果您的Hibernate应用程序是注释驱动的,它实际上可能不需要JAXB的任何实现,在这种情况下,您可以只包含JAXB API。以下是我添加到POM中的依赖项:

    <!-- JAXB API -->
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.11</version>
    </dependency>
    

    解决了JAXB问题后,我运行了该应用程序,并收到了数千行堆栈跟踪,如下所示:

    java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @49f97198
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
        at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:197)
        at java.base/java.lang.reflect.Method.setAccessible(Method.java:191)
        at javassist.util.proxy.SecurityActions.setAccessible(SecurityActions.java:103)
        at javassist.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:181)
        at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:164)
        at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:507)
        at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:492)
        at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:428)
        at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:400)
        at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.postInstantiate(JavassistProxyFactory.java:72)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:162)
        at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:163)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:58)
    

    在这些异常之后,您的应用程序可能看起来运行正常。但是不要被愚弄:对象的惰性初始化已经被禁用。因此,您可能会遇到严重的性能问题。

    出现这些错误是因为新模块系统中的强封装规则阻止了Hibernate的运行时字节码增强。请参阅这篇stackoverflow文章,以获得对此问题的详细描述。

      null

    这避免了Hibernate在运行时执行基于JavAssist的类修改的需要,消除了上面显示的堆栈跟踪。我用Hibernate 5.0.12.final、5.1.5.final和5.2.9.final测试了这一点。

    但是,您应该在之后彻底测试您的应用程序。Hibernate在构建时应用的字节码更改与在运行时应用的字节码更改似乎不同,导致应用程序行为略有不同。当我启用构建时字节码增强时,在我的应用程序中成功多年的单元测试突然失败了。(我不得不查找新的LazyInitializationException错误和其他问题。)而且行为似乎在Hibernate的一个版本和另一个版本之间有所不同;我可以修复我的单元测试在5.0.12中工作,但却看到它们在5.1.5中再次失败。谨慎行事。

  •  类似资料:
    • Java9(特别是拼图)中是否有任何计划来支持Java监控代理的特殊要求? 通常,监视代理需要访问类、包和模块的能力,这些类、包、模块在默认情况下对原始Java应用程序是不可用的。通过-javaagent命令行参数加载到JVM中的监控代理不会作为模块加载,即使jar文件包含模块信息。类文件。我能够为我的监控代理提供所需权限的唯一方法是添加命令行参数,将这些权限提供给所有未命名的模块。

    • 我在Java 8中构建了一个EAR,它在WAS 9中工作得很好,但如果我在Java 9中编译,EAR将无法工作,并抛出如下错误: WebSphere 9是否支持Java9?

    • 我知道有一个插件Java9支持Oxygen,但是有人知道Eclipse何时会在本地支持Java9吗?我查看了项目网站和博客(行星月食),但找不到任何信息。

    • 问题内容: 我无法让Hibernate使用PostgreSQL的java.util.UUID。 这是使用javax.persistence。*批注的映射: 当持久化一个临时对象时,我得到一个SQLGrammarException: PostgreSQL版本是8.4.4 JDBC驱动程序-8.4.4-702(也尝试过9.0-相同) Hibernate版本是3.6,主要配置属性: 问题答案: 可以通过

    • 默认情况下,Hibernate支持一对多/多对一和多对多关联的惰性加载。但Hibernate不支持一对一关系的延迟加载。让我们为父场景和子场景提供以下示例。 一个人有一个地址父实体定义为。 子实体定义为 在上面的场景中,它应该是惰性加载,但实际上hibernate正在产生急切的加载。两个select语句同时激发1)select用于父实体,在本例中为Person;2)select用于子实体,在本例中

    • Java9的一个新特性是不推荐使用包装对象的构造函数。创建新包装对象的唯一方法是使用它们的静态方法。例如,对于整数对象,为-128和127之间的值实现缓存,并在每次调用时返回相同的引用。 正如类的API所说:“静态工厂值of(int)通常是一个更好的选择,因为它可能会产生更好的空间和时间性能。”JLS说:“给定相应的基元类型的值,通常不需要构造这些box类的新实例。构造的建议替代方法是自动装箱或静