5

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?

SternK
  • 11,649
  • 22
  • 32
  • 46
Yaroslav
  • 118
  • 1
  • 8
  • 1
    See [this](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#basic). By default hibernate use java.lang.String for `CLOB` JDBC type. Otherwise, you should use [custom hibernate type](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#basic-custom-type). – SternK Nov 18 '19 at 10:25
  • @SternK, thanks for your reply! Unfortunately, I still have no understanding **why** does incorrect type cause metamodel property missing. I've tried to google for it, but had no result. Couldn't you, please, point to a doc section or give a brief explanation of that? Thanks in advance! – Yaroslav Nov 18 '19 at 12:06
  • Could you explain, why you want to declare `x, y` fields as `java.lang.Object`? What do you want to achieve? – SternK Nov 18 '19 at 14:07
  • Honestly, I have no idea. It's legacy code and I just tried to figure out, why some of metamodel's attributes are missing. In fact, there are few cases where fields are actually BLOBs. Most of them are just VARCHARs. Taking in account your first comment, I think it would be better just to fix types in Java code – Yaroslav Nov 18 '19 at 14:27

1 Answers1

11

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.

Community
  • 1
  • 1
SternK
  • 11,649
  • 22
  • 32
  • 46