Hibernate.orgCommunity Documentation

Chapter 4. Metamodel

4.1. Static metamodel

Note

The Metamodel itself is described in Chapter 5 Metamodel API of the [JPA 2 Specification]. Chapter 6 Criteria API of the [JPA 2 Specification] describes and shows uses of the metamodel in criteria queries, as does Chapter 9, Criteria Queries.

The metamodel is a set of objects that describe your domain model. javax.persistence.metamodel.Metamodel acts as a repository of these metamodel objects and provides access to them, and can be obtained from either the javax.persistence.EntityManagerFactory or the javax.persistence.EntityManager via their getMetamodel method.

This metamodel is important in 2 ways. First, it allows providers and frameworks a generic way to deal with an application's domain model. Persistence providers will already have some form of metamodel that they use to describe the domain model being mapped. This API however defines a single, independent access to that existing information. A validation framework, for example, could use this information to understand associations; a marshaling framework might use this information to decide how much of an entity graph to marshal. This usage is beyond the scope of this documentation.

Important

As of today the JPA 2 metamodel does not provide any facility for accessing relational information pertaining to the physical model. It is expected this will be addressed in a future release of the specification.

Second, from an application writer's perspective, it allows very fluent expression of completely type-safe criteria queries, especially the Static Metamodel approach. The [JPA 2 Specification] defines a number of ways the metamodel can be accessed and used, including the Static Metamodel approach, which we will look at later. The Static Metamodel approach is wonderful when the code has a priori knowledge of the domain model. Chapter 9, Criteria Queries uses this approach exclusively in its examples.

A static metamodel is a series of classes that "mirror" the entities and embeddables in the domain model and provide static access to the metadata about the mirrored class's attributes. We will exclusively discuss what the [JPA 2 Specification] terms a Canonical Metamodel:

 

  • For each managed class X in package p, a metamodel class X_ in package p is created.

  • The name of the metamodel class is derived from the name of the managed class by appending "_" to the name of the managed class.

  • The metamodel class X_ must be annotated with the javax.persistence.StaticMetamodelannotation [1]

  • If class X extends another class S, where S is the most derived managed class (i.e., entity or mapped superclass) extended by X, then class X_ must extend class S_, where S_ is the metamodel class created for S.

  • 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;

  • For every persistent collection-valued attribute z declared by class X, where the element type of z is Z, the metamodel class must contain a declaration as follows:

    • if the collection type of z is java.util.Collection, then

      public static volatile CollectionAttribute<X, Z> z;

    • if the collection type of z is java.util.Set, then

      public static volatile SetAttribute<X, Z> z;

    • if the collection type of z is java.util.List, then

      public static volatile ListAttribute<X, Z> z;

    • if the collection type of z is java.util.Map, then

      public static volatile MapAttribute<X, K, Z> z;

      where K is the type of the key of the map in class X

Import statements must be included for the needed javax.persistence.metamodel types as appropriate (e.g., javax.persistence.metamodel.SingularAttribute, javax.persistence.metamodel.CollectionAttribute, javax.persistence.metamodel.SetAttribute, javax.persistence.metamodel.ListAttribute, javax.persistence.metamodel.MapAttribute) and all classes X, Y, Z, and K.

 
 -- [JPA 2 Specification, section 6.2.1.1, pp 198-199]

Note

These canonical metamodel classes can be generated manually if you wish though it is expected that most developers will prefer use of an annotation processor. Annotation processors themselves are beyond the scope of this document. However, the Hibernate team does develop an annotation processor tool for generating a canonical metamodel. See Hibernate Metamodel Generator.

When the Hibernate EntityManagerFactory is being built, it will look for a canonical metamodel class for each of the managed typed is knows about and if it finds any it will inject the appropriate metamodel information into them, as outlined in [JPA 2 Specification, section 6.2.2, pg 200]



[1] (from the original) If the class was generated, the javax.annotation.Generated annotation should be used to annotate the class. The use of any other annotations on static metamodel classes is undefined.