javahibernatejpageneratormetamodel

Why I get HHH015011: Unable to locate static metamodel field?


I have to deal with a view declared as following (Oracle 11g):

  create view V_SOME_VIEW as
  select X, Y
  from SOME_TABLE

and an entity for it:

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;

   ...    
}

After generating a static metamodel using Gradle Metamodel Plugin I have the following metamodel without attribute 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";
}

At application start I have errors like this:

ERROR o.h.ejb.metamodel.MetadataContext: HHH015011: Unable to locate static metamodel field: ...VSomeView_#y

If I change column type from java.lang.Object to java.lang.String the field y is generated correctly. Can someone explain me, what's the reason for this, please?


Solution

  • From JPA specification

    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;

    So, from this point of view, your expectation to see y property in the metamodel class looks substantiated.

    But diving into the Hibernate implementation of the annotation processor 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 true.

    It is possible in the following cases:

    1. The persistent attribute is annotated by one of the following annotations: @Basic, @OneToOne, @ManyToOne, @EmbeddedId, @Id.

    2. The persistent attribute is annotated with the annotation @Type what means it is a hibernate custom type.

    3. The persistent attribute is an enum.

    4. The persistent attribute is a primitive type

    5. The persistent attribute is a hibernate basic type

    6. The persistent attribute is a class that implements Serializable interface.

    7. The persistent attribute is a class annotated with the @Embeddable annotation.

    Your first persistent attribute meet the n.1 condition due to the @Id annotation, but the second one does not meet n.1-7 conditions that is why it is absent in the generated metamodel.

    See also this.