我必须处理声明为以下内容的视图(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";
}


在应用程序启动时,我会遇到如下错误:


  错误o.h.ejb.metamodel.MetadataContext:HHH015011:无法找到静态元模型字段:... VSomeView_#y


如果我将列类型从java.lang.Object更改为java.lang.String,则字段y正确生成。有人可以解释一下,这是什么原因?

最佳答案

从JPA规范


  6.2.1.1规范元模型
  
  对于类y声明的每个持久性非集合值属性X,其中y的类型为Y,元模型类必须包含如下声明:
  
  public static volatile SingularAttribute<X, Y> y;


因此,从这个角度来看,您希望看到metamodel类中的y属性看起来得到了证实。

但是深入了解注释处理器的Hibernate实现
JPAMetaModelEntityProcessor,我们可以发现,如果类MetaAttributeGenerationVisitor的isBasicAttribute方法返回true,则在元模型类中将出现非集合值的属性。

在以下情况下有可能:


持久属性由以下注释之一进行注释:
@Basic@OneToOne@ManyToOne@EmbeddedId@Id
持久属性用注释@Type注释,这意味着它是休眠的自定义类型。
持久属性为an enum
持久属性为a primitive type
持久属性为a hibernate basic type
持久属性是实现Serializable接口的类。
持久属性是一个用@Embeddable注释注释的类。


由于@Id批注,您的第一个持久属性满足n.1条件,但是第二个持久属性不满足n.1-7条件,这就是为什么在生成的元模型中不存在该属性。

另请参见this

10-07 16:08