在Java 9上使用eclipselink进行静态编织与最终字段 [英] eclipselink static weaving with final fields on Java 9

查看:75
本文介绍了在Java 9上使用eclipselink进行静态编织与最终字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些声明为final的JPA注释字段,如下所示:

I have some JPA annotated fields declared final like this:

@Column(name = "SOME_FIELD", updatable = false, nullable = false)
private final String someField;

将实体插入数据库时​​,这些字段将存储在数据库中.它们无法进一步更新.对于Java编程语言,可以将这些字段视为最终字段.

Those fields are stored in the database when the entity is inserted in the database. They cannot further be updated. For the Java programming language, such fields can be considered final.

使用EclipseLink静态编织插件,由于某些字节代码检测,可以延迟加载实体.

With the EclipseLink static weaving plugin, it's possible to lazy load entities, owing to some byte code instrumentation.

我不知道JPA中是否正式允许使用此类构造(最终字段),但我喜欢使用它们,因为它们在编译时会强制要求这些字段不被更新.

I don't know if such constructs (final fields) are officially allowed in JPA, but I like to use them, since they enforce at compile time that these fields are not meant to be updated.

在Java 8中,使用这种构造构建的程序运行良好.但是在Java 9中,当涉及EclipseLink静态编织时,我得到以下运行时异常:

In Java 8, programs built with such constructs run fine. But in Java 9, when the EclipseLink static weaving is involved, I get the following runtime exception:

Caused by: java.lang.IllegalAccessError: Update to non-static final field xxx.yyy.SomeEntity.someField attempted from a different method (_persistence_set) than the initializer method <init> 

这种错误似乎是由于以下JVM规范引起的:

Such an error seems to be due to the following JVM specification:

否则,如果该字段为final,则必须在当前字段中声明该字段 类,并且指令必须在实例初始化中发生 当前类的方法().否则,会出现IllegalAccessError 被抛出.

Otherwise, if the field is final, it must be declared in the current class, and the instruction must occur in an instance initialization method () of the current class. Otherwise, an IllegalAccessError is thrown.

因此,我觉得某些编织工具需要一些更新才能满足此JVM规范. EclipseLink静态编织工具似乎就是其中之一.

Therefore, I feel like some weaving tools need some update to fulfill this JVM specification. The EclipseLink static weaving tool seems to be one of them.

问题:

  • JPA是否允许最终的现场结构(如此处介绍的结构)?
  • 是否只有一个JDK 9选项可以禁用对最终字段分配的检查,而不仅仅是在类的实例初始化method()中(作为临时解决方法)?

修改:

根据JPA规范,JPA中不允许使用最终字段:

Final fields are not allowed in JPA, as per JPA specifications:

实体类不能是最终的.实体类的任何方法或持久性实例变量都不得是最终的.

The entity class must not be final. No methods or persistent instance variables of the entity class may be final.

推荐答案

请阅读JPA规范-

Please read JPA specification - http://download.oracle.com/otndocs/jcp/persistence-2_2-mrel-eval-spec/index.html - Section 2.1 The Entity Class:

实体类不能是最终的.实体类的任何方法或持久实例变量都不能是最终的.

方法_persistence_set是通过编织(对实体类的字节码操作)添加的代码,用于在默认构造函数(无属性)调用创建类之后初始化实体属性的值. Java 1.8甚至允许在最终字段中都允许这样做,但是Java 9不允许.

Method _persistence_set is code added by weaving (bytecode manipulation of entity classes) and is used to initialize values of entity attributes after class was created by default constructor (with no attributes) call. Java 1.8 allowed this even with final fields, but Java 9 does not.

您现在应该遵循JPA规范,并且不应将最终的持久性属性放入实体中.

You should now follow JPA specification and should not put final persistence attributes into your entities.

这篇关于在Java 9上使用eclipselink进行静态编织与最终字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆