为什么我得到 HHH015011:无法定位静态元模型字段?
Why I get HHH015011: Unable to locate static metamodel field?
我必须处理如下声明的视图 (Oracle 11g):
create view V_SOME_VIEW as
select X, Y
from SOME_TABLE
及其实体:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
@Entity
@Table("V_SOME_VIEW")
@NamedQueries({
@NamedQuery(name = "VSomeView.findAll", query = "SELECT v FROM VSomeView v")})
public class VSomeView implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Lob
@Column(name = "X")
private Object x;
@Lob
@Column(name = "Y")
private Object y;
...
}
使用 Gradle Metamodel Plugin 生成静态元模型后,我有以下元模型 没有属性 y:
import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(VSomeView.class)
public abstract class VSomeView_ {
public static volatile SingularAttribute<VSomeView, Object> x;
public static final String X = "x";
}
在应用程序启动时出现如下错误:
ERROR o.h.ejb.metamodel.MetadataContext: HHH015011: Unable to locate static metamodel field: ...VSomeView_#y
如果我将列类型从 java.lang.Object
更改为 java.lang.String
,则会正确生成字段 y。谁能解释一下,请问这是什么原因?
来自 JPA 规范
6.2.1.1 Canonical Metamodel
For every persistent non-collection-valued attribute y
declared by class X
, where the type of y
is Y
, the metamodel class must contain a declaration as follows:
public static volatile SingularAttribute<X, Y> y;
因此,从这个角度来看,您对在元模型 class 中看到 y
属性 的期望看起来得到证实。
但深入研究注解处理器的 Hibernate 实现
JPAMetaModelEntityProcessor, we can find out that a non-collection-valued attribute will be present at the metamodel class if the method isBasicAttribute of the class MetaAttributeGenerationVisitor returns 真.
以下情况是可以的:
持久属性由以下注释之一进行注释:
@Basic, @OneToOne, @ManyToOne, @EmbeddedId, @Id.
persistent 属性用注释 @Type 注释,这意味着它是休眠自定义类型。
永久属性为an enum。
持久属性为a primitive type
-
持久化属性是一个实现了Serializable接口的class。
永久属性是一个 class 注释 @Embeddable 注释。
由于 @Id
注释,您的第一个持久属性满足 n.1 条件,但第二个不满足 n.1-7 条件,这就是它在生成的元模型中不存在的原因。
另见 this。
我必须处理如下声明的视图 (Oracle 11g):
create view V_SOME_VIEW as
select X, Y
from SOME_TABLE
及其实体:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
@Entity
@Table("V_SOME_VIEW")
@NamedQueries({
@NamedQuery(name = "VSomeView.findAll", query = "SELECT v FROM VSomeView v")})
public class VSomeView implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Lob
@Column(name = "X")
private Object x;
@Lob
@Column(name = "Y")
private Object y;
...
}
使用 Gradle Metamodel Plugin 生成静态元模型后,我有以下元模型 没有属性 y:
import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(VSomeView.class)
public abstract class VSomeView_ {
public static volatile SingularAttribute<VSomeView, Object> x;
public static final String X = "x";
}
在应用程序启动时出现如下错误:
ERROR o.h.ejb.metamodel.MetadataContext: HHH015011: Unable to locate static metamodel field: ...VSomeView_#y
如果我将列类型从 java.lang.Object
更改为 java.lang.String
,则会正确生成字段 y。谁能解释一下,请问这是什么原因?
来自 JPA 规范
6.2.1.1 Canonical Metamodel
For every persistent non-collection-valued attribute
y
declared by classX
, where the type ofy
isY
, the metamodel class must contain a declaration as follows:
public static volatile SingularAttribute<X, Y> y;
因此,从这个角度来看,您对在元模型 class 中看到 y
属性 的期望看起来得到证实。
但深入研究注解处理器的 Hibernate 实现 JPAMetaModelEntityProcessor, we can find out that a non-collection-valued attribute will be present at the metamodel class if the method isBasicAttribute of the class MetaAttributeGenerationVisitor returns 真.
以下情况是可以的:
持久属性由以下注释之一进行注释: @Basic, @OneToOne, @ManyToOne, @EmbeddedId, @Id.
persistent 属性用注释 @Type 注释,这意味着它是休眠自定义类型。
永久属性为an enum。
持久属性为a primitive type
持久化属性是一个实现了Serializable接口的class。
永久属性是一个 class 注释 @Embeddable 注释。
由于 @Id
注释,您的第一个持久属性满足 n.1 条件,但第二个不满足 n.1-7 条件,这就是它在生成的元模型中不存在的原因。
另见 this。