Module jakarta.data

Annotation Interface StaticMetamodel


@Documented @Retention(RUNTIME) @Target(TYPE) public @interface StaticMetamodel

Annotates a class which serves as a static metamodel for an entity, enabling type-safe access to entity attribute names and related objects such as instances of Sorts for an attribute. A metamodel class contains one or more public static fields corresponding to attributes of the entity class. The type of each of these fields must be either String, Attribute, or a subinterface of Attribute defined in this package.

The following subinterfaces of Attribute are recommended to obtain the full benefit of the static metamodel:

Jakarta Data defines the following conventions for static metamodel classes:

  • The metamodel class can be an interface or concrete class.
  • The name of the static metamodel class should consist of underscore (_) followed by the entity class name.
  • Fields of type String should be named with all upper case.
  • Fields that are subtypes of Attribute should be named in lower case or mixed case.

For example, for the following entity,


 @Entity
 public class Person {
     public LocalDate dateOfBirth;

     @Embedded
     public Name name;

     @Id
     public long ssn;
 }

 @Embeddable
 public class Name {
     public String first;
     public String last;
 }
 

An application programmer may define a static metamodel as follows,


 @StaticMetamodel(Person.class)
 public interface _Person {
     String DATEOFBIRTH = "dateOfBirth";
     String NAME = "name";
     String NAME_FIRST = "name.first";
     String NAME_LAST = "name.last";
     String SSN = "ssn";

     TemporalAttribute<Person, LocalDate> dateOfBirth = TemporalAttribute.of(
             Person.class, DATEOFBIRTH, LocalDate.class);
     NavigableAttribute<Person, Name> name = NavigableAttribute.of(
             Person.class, NAME, Name.class);
     TextAttribute<Person> name_first = TextAttribute.of(
             Person.class, NAME_FIRST);
     TextAttribute<Person> name_last = TextAttribute.of(
             Person.class, NAME_LAST);
     NumericAttribute<Person, Long> ssn = NumericAttribute.of(
             Person.class, SSN, long.class);
 }
 

And use it to refer to entity attributes in a type-safe manner,


 Order<Person> order =
         Order.by(_Person.dateOfBirth.desc(),
                  _Person.name_last.asc(),
                  _Person.name_first.asc(),
                  _Person.ssn.asc());
 

Alternatively, an annotation processor might generate static metamodel classes for entities at compile time. The generated classes must be annotated with the @Generated annotation. The fields may be statically initialized, or they may be initialized by the provider during system initialization. In the first case, the fields are declared final and the metamodel class can be an interface. In the second case, the fields are declared non-final and volatile and the metamodel class must be a concrete class.

In cases where multiple Jakarta Data providers provide repositories for the same entity type, no guarantees are made of the order in which the Jakarta Data providers attempt to initialize the fields of the static metamodel class for that entity.

  • Required Element Summary

    Required Elements
    Modifier and Type
    Required Element
    Description
    An entity class.
  • Element Details

    • value

      Class<?> value
      An entity class.
      Returns:
      the entity class.