HHH-4949 - Document JPA 2 metamodel
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18874 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
3df8bc5712
commit
1fa3112156
|
@ -70,6 +70,7 @@
|
|||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/architecture.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/configuration.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/entitymanagerapi.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/metamodel.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/transactions.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/listeners.xml"/>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/batch.xml"/>
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY jpa2Biblio '<xref linkend="JPA2"/>'>
|
||||
<!ENTITY jpa2Cite '<citation>&jpa2Biblio;</citation>'>
|
||||
<!ENTITY criteriaRef '<xref linkend="querycriteria"/>'>
|
||||
<!ENTITY apt '<ulink url="http://java.sun.com/javase/6/docs/technotes/tools/solaris/javac.html#processing">annotation processor</ulink>'>
|
||||
]>
|
||||
|
||||
<chapter id="metamodel">
|
||||
<title>Metamodel</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The Metamodel itself is described in <citetitle pubwork="chapter">Chapter 5 Metamodel API</citetitle>
|
||||
of the &jpa2Cite;. <citetitle pubwork="chapter">Chapter 6 Criteria API</citetitle> of the &jpa2Cite;
|
||||
describes and shows uses of the metamodel in criteria queries, as does &criteriaRef;.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The metamodel is a set of objects that describe your domain model.
|
||||
<interfacename>javax.persistence.metamodel.Metamodel</interfacename> acts as a repository of these metamodel
|
||||
objects and provides access to them. We ask either the
|
||||
<interfacename>javax.persistence.EntityManagerFactory</interfacename> or the
|
||||
<interfacename>javax.persistence.EntityManager</interfacename> for a reference to the
|
||||
<interfacename>javax.persistence.metamodel.Metamodel</interfacename> via their
|
||||
<methodname>getMetamodel</methodname> method.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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 simply allows general 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.
|
||||
</para>
|
||||
|
||||
<important>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</important>
|
||||
|
||||
<para>
|
||||
Second, from an application writer's perspective, it allows very fluent expression of completely type-safe
|
||||
criteria queries, especially the <emphasis>Static Metamodel</emphasis> approach. The &jpa2Cite; defines a
|
||||
number of ways the metamodel can be accessed and used, including the <emphasis>Static Metamodel</emphasis>
|
||||
approach, which we will look at later. The <emphasis>Static Metamodel</emphasis> approach is wonderful
|
||||
when the code has <ulink url="http://en.wikipedia.org/wiki/A_priori_and_a_posteriori">a priori knowledge</ulink>
|
||||
of the domain model. &criteriaRef; uses this approach exclusively in its examples.
|
||||
</para>
|
||||
|
||||
<section id="metamodel-static">
|
||||
<title>Static metamodel</title>
|
||||
<para>
|
||||
A <emphasis>static metamodel</emphasis> 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 &jpa2Cite; terms a <emphasis>Canonical Metamodel</emphasis>:
|
||||
</para>
|
||||
|
||||
<blockquote>
|
||||
<attribution>
|
||||
<citation><xref linkend="JPA2"/>, section 6.2.1.1, pp 198-199</citation>
|
||||
</attribution>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For each managed class <classname>X</classname> in package <package>p</package>,
|
||||
a metamodel class <classname>X_</classname> in package <package>p</package> is created.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the metamodel class is derived from the name of the managed class by appending
|
||||
"_" to the name of the managed class.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The metamodel class <classname>X_</classname> must be annotated with the
|
||||
<interfacename>javax.persistence.StaticMetamodel</interfacename>annotation
|
||||
<footnote>
|
||||
<para>
|
||||
<emphasis>(from the original)</emphasis> If the class was generated, the
|
||||
<interfacename>javax.annotation.Generated</interfacename> annotation should be
|
||||
used to annotate the class. The use of any other annotations on static metamodel
|
||||
classes is undefined.
|
||||
</para>
|
||||
</footnote>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If class <classname>X</classname> extends another class <classname>S</classname>, where
|
||||
<classname>S</classname> is the most derived managed class (i.e., entity or mapped
|
||||
superclass) extended by <classname>X</classname>, then class <classname>X_</classname> must
|
||||
extend class <classname>S_</classname>, where <classname>S_</classname> is the metamodel
|
||||
class created for <classname>S</classname>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For every persistent non-collection-valued attribute <emphasis>y</emphasis> declared by
|
||||
class <classname>X</classname>, where the type of <emphasis>y</emphasis> is
|
||||
<classname>Y</classname>, the metamodel class must contain a declaration as follows:
|
||||
<programlisting><![CDATA[public static volatile SingularAttribute<X, Y> y;]]></programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For every persistent collection-valued attribute <emphasis>z</emphasis> declared by class
|
||||
<classname>X</classname>, where the element type of <emphasis>z</emphasis> is
|
||||
<classname>Z</classname>, the metamodel class must contain a declaration as follows:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
if the collection type of <emphasis>z</emphasis> is
|
||||
<interfacename>java.util.Collection</interfacename>, then
|
||||
<programlisting><![CDATA[public static volatile CollectionAttribute<X, Z> z;]]></programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if the collection type of <emphasis>z</emphasis> is
|
||||
<interfacename>java.util.Set</interfacename>, then
|
||||
<programlisting><![CDATA[public static volatile SetAttribute<X, Z> z;]]></programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if the collection type of <emphasis>z</emphasis> is
|
||||
<interfacename>java.util.List</interfacename>, then
|
||||
<programlisting><![CDATA[public static volatile ListAttribute<X, Z> z;]]></programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if the collection type of <emphasis>z</emphasis> is
|
||||
<interfacename>java.util.Map</interfacename>, then
|
||||
<programlisting><![CDATA[public static volatile MapAttribute<X, K, Z> z;]]></programlisting>
|
||||
where <classname>K</classname> is the type of the key of the map in class
|
||||
<classname>X</classname>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Import statements must be included for the needed <package>javax.persistence.metamodel</package> types
|
||||
as appropriate (e.g., <interfacename>javax.persistence.metamodel.SingularAttribute</interfacename>,
|
||||
<interfacename>javax.persistence.metamodel.CollectionAttribute</interfacename>,
|
||||
<interfacename>javax.persistence.metamodel.SetAttribute</interfacename>,
|
||||
<interfacename>javax.persistence.metamodel.ListAttribute</interfacename>,
|
||||
<interfacename>javax.persistence.metamodel.MapAttribute</interfacename>) and all classes
|
||||
<classname>X</classname>, <classname>Y</classname>, <classname>Z</classname>, and <classname>K</classname>.
|
||||
</para>
|
||||
</blockquote>
|
||||
|
||||
<example id="metamodel-static-ex">
|
||||
<title>Static metamodel example</title>
|
||||
<para>
|
||||
For the <classname>Person</classname> entity
|
||||
<programlisting><![CDATA[package org.hibernate.jpa2.metamodel.example;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
@Id private Long id;
|
||||
private String name;
|
||||
private int age;
|
||||
private Address address;
|
||||
@OneToMany private Set<Order> orders;
|
||||
}]]></programlisting>
|
||||
The corresponding canonical metamodel class, <classname>Person_</classname> would look like
|
||||
<programlisting><![CDATA[package org.hibernate.jpa2.metamodel.example;
|
||||
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
import javax.persistence.metamodel.SetAttribute;
|
||||
import javax.persistence.metamodel.StaticMetamodel;
|
||||
|
||||
@StaticMetamodel( Person.class )
|
||||
public class Person_ {
|
||||
public static volatile SingularAttribute<Person, Long> id;
|
||||
public static volatile SingularAttribute<Person, String> name;
|
||||
public static volatile SingularAttribute<Person, Integer> age;
|
||||
public static volatile SingularAttribute<Person, Address> address;
|
||||
public static volatile SetAttribute<Person, Order> orders;
|
||||
}]]></programlisting>
|
||||
</para>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
These canonical metamodel classes can be generated manually if you wish though it is expected
|
||||
that most developers will prefer use of an &apt;. Although annotation processors themselves are
|
||||
beyond the scope of this document, the Hibernate team does develop an annotation processor tool for
|
||||
generating a canonical metamodel. See <citetitle>Hibernate Metamodel Generator</citetitle>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
When the Hibernate <interfacename>EntityManagerFactory</interfacename> 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
|
||||
<citation><xref linkend="JPA2"/>, section 6.2.2, pg 200</citation>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
Loading…
Reference in New Issue