<?xml version="1.0" encoding="UTF-8"?>
<chapter id="sid-54493688">
   <title>Errai JPA</title>
   <para>Starting with Errai 2.1, Errai implements a subset of JPA 2.0. With Errai JPA, you can store and retrieve entity objects on the client side, in the browser's local storage. This allows the reuse of JPA-related code (both entity class definitions and procedural logic that uses the EntityManager) between client and server.</para>
   <para>Errai JPA implements the following subset of JPA 2.0:</para>
   <itemizedlist>
      <listitem>
         <para>Annotation-based configuration</para>
      </listitem>
      <listitem>
         <para>Entity Types with</para>
         <itemizedlist>
            <listitem>
               <para>Identifiers of any numeric type (int, long, short, etc.)</para>
               <itemizedlist>
                  <listitem>
                     <para>Generated identifiers</para>
                  </listitem>
               </itemizedlist>
            </listitem>
            <listitem>
               <para>Regular attributes of any JPA Basic type (Java primitive types, boxed primitives, enums, BigInteger, BigDecimal, String, Date, Time, and Timestamp)</para>
            </listitem>
            <listitem>
               <para>Singular and Plural (collection-valued) attributes of other entity types</para>
               <itemizedlist>
                  <listitem>
                     <para>All association types (one-to-one, one-to-many, many-to-one, many-to-many)</para>
                  </listitem>
                  <listitem>
                     <para>All association cascade rules (ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH)</para>
                  </listitem>
                  <listitem>
                     <para>Circular and self references work properly</para>
                  </listitem>
               </itemizedlist>
            </listitem>
            <listitem>
               <para>Property access by field or get/set methods</para>
            </listitem>
         </itemizedlist>
      </listitem>
      <listitem>
         <para>Named, typed JPQL queries that select exactly one entity type</para>
         <itemizedlist>
            <listitem>
               <para>With cascading fetch of related entities</para>
            </listitem>
            <listitem>
               <para>
              With or without
              <code>WHERE</code>
              clause
            </para>
               <itemizedlist>
                  <listitem>
                     <para>All boolean, arithmetic, and string operators supported</para>
                  </listitem>
                  <listitem>
                     <para>All String manipulation functions supported</para>
                  </listitem>
               </itemizedlist>
            </listitem>
            <listitem>
               <para>
              With or without
              <code>ORDER BY</code>
              clause
            </para>
            </listitem>
         </itemizedlist>
      </listitem>
      <listitem>
         <para>Lifecycle events and entity lifecycle listeners</para>
      </listitem>
      <listitem>
         <para>
          Much of the Metamodel API (
          <code>Metamodel</code>
          ,
          <code>EntityType</code>
          ,
          <code>SingularAttribute</code>
          ,
          <code>PluralAttribute</code>
          , etc.)
        </para>
      </listitem>
   </itemizedlist>
   <important>
      <title>It's all client-side</title>
      <para>
        Errai JPA is a declarative, typesafe interface to the web browser's
        <code>localStorage</code>
        object. As such it is a
        <emphasis role="strong">client-side implementation</emphasis>
        of JPA. Objects are stored and fetched from the browser's local storage,
        <emphasis role="italics">not</emphasis>
        from the JPA provider on the server side.
      </para>
   </important>
   <section id="sid-54493688_ErraiJPA-GettingStarted">
      <title>Getting Started</title>
      <section id="sid-54493688_ErraiJPA-Compiletimedependency">
         <title>Compile-time dependency</title>
         <para>To use Errai UI Navigation, you must include it on the compile-time classpath. If you are using Maven for your build, add this dependency:</para>
         <informalexample>
            <programlisting language="xml">
    &lt;dependency&gt;
      &lt;groupId&gt;org.jboss.errai&lt;/groupId&gt;
      &lt;artifactId&gt;errai-jpa-client&lt;/artifactId&gt;
      &lt;version&gt;${errai.version}&lt;/version&gt;
    &lt;/dependency&gt;
</programlisting>
         </informalexample>
         <para>
          If you are not using Maven for dependency management, add
          <code>errai-jpa-client-version.jar</code>
          , Hibernate 4.1.1, and Google Guava for GWT 12.0 to your compile-time classpath.
        </para>
      </section>
      <section id="sid-54493688_ErraiJPA-GWTModuleDescriptor">
         <title>GWT Module Descriptor</title>
         <para>
          Once you have Errai UI Navigation on your classpath, ensure your application inherits the GWT module as well. Add this line to your application's
          <code>*.gwt.xml</code>
          file:
        </para>
         <informalexample>
            <programlisting language="xml">
   &lt;inherits name="org.jboss.errai.jpa.JPA"/&gt;
</programlisting>
         </informalexample>
      </section>
      <section id="sid-54493688_ErraiJPA-METAINF%2Fpersistence.xml">
         <title>INF/persistence.xml</title>
         <para>You need to have a META-INF/persistence.xml file on the classpath that defines a persistence unit. This persistence unit should declare every entity class you want to use with the client-side JPA provider.</para>
         <para>Example:</para>
         <informalexample>
            <programlisting language="xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"&gt;

  &lt;persistence-unit name="ErraiJpaDemo"&gt;
    &lt;description&gt;Entities used in the browser&lt;/description&gt;
    &lt;class&gt;com.company.app.client.shared.Album&lt;/class&gt;
    &lt;class&gt;com.company.app.client.shared.Artist&lt;/class&gt;
    &lt;class&gt;com.company.app.client.shared.Genre&lt;/class&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;
</programlisting>
         </informalexample>
      </section>
      <section id="sid-54493688_ErraiJPA-DeclaringanEntityClass">
         <title>Declaring an Entity Class</title>
         <para>
          Classes whose instances can be stored and retrieved by JPA are called
          <emphasis role="italics">entities</emphasis>
          . To declare a class as a JPA entity, annotate it with
          <code>@Entity</code>
          .
        </para>
         <para>JPA requires that entity classes conform to a set of rules. These are:</para>
         <itemizedlist>
            <listitem>
               <para>The class must have an ID attribute</para>
            </listitem>
            <listitem>
               <para>The class must have a public or protected constructor that takes no arguments</para>
            </listitem>
            <listitem>
               <para>The class must be public and nonfinal</para>
            </listitem>
            <listitem>
               <para>No methods or persistent fields of the class may be final</para>
            </listitem>
            <listitem>
               <para>The class must be a top-level type (not a nested or inner class)</para>
            </listitem>
         </itemizedlist>
         <para>
          Here is an example of a valid entity class with an ID attribute (
          <code>id</code>
          ) and a String-valued  persistent attribute (
          <code>name</code>
          ):
        </para>
         <informalexample>
            <programlisting language="java">
@Entity
public class Genre {

  @Id @GeneratedValue
  private int id;

  private String name;

  // This constructor is used by JPA
  public Genre() {}

  // This constructor is not used by JPA
  public Genre(String name) {
    this();
    this.name = name;
  }


  // These getter and Setter methods are optional:

  public int getId() { return id; }
  public void setId(int id) { this.id = id; }

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
}
</programlisting>
         </informalexample>
         <section id="sid-54493688_ErraiJPA-EntityAttributes">
            <title>Entity Attributes</title>
            <para>
            The state of fields and JavaBeans properties of entities are generally persisted with the entity instance. These persistent things are called
            <emphasis role="italics">attributes</emphasis>
            .
          </para>
            <para>
            JPA Attributes are subdivided into two main types:
            <emphasis role="italics">singular</emphasis>
            and
            <emphasis role="italics">plural</emphasis>
            . Singular attributes are scalar types like
            <code>Integer</code>
            or
            <code>String</code>
            . Plural attributes are collection values, such as
            <code>List&lt;Integer&gt;</code>
            or
            <code>Set&lt;String&gt;</code>
            .
          </para>
            <para>
            The values of singular attributes (and the elements of plural attributes) can be of any application-defined entity type or a JPA Basic type. The JPA basic types are all of the Java primitive types, all boxed primitives, enums, BigInteger, BigDecimal, String, Date (
            <code>java.util.Date</code>
            or
            <code>java.sql.Date</code>
            ), Time, and Timestamp.
          </para>
            <para>
            You can direct JPA to read and write your entity's attributes by direct field access or via JavaBeans property access methods (that is, "getters and setters"). Direct field access is the default. To request property access, annotate the class with
            <code>@Access(AccessType.PROPERTY)</code>
            . If using direct field access, attribute-specific JPA annotations should be on the fields themselves; when using property access, the attribute-specific annotations should be on the getter method for that property.
          </para>
         </section>
         <section id="sid-54493688_ErraiJPA-IDAttributesandAutoGeneratedIdentifiers">
            <title>ID Attributes and Auto-Generated Identifiers</title>
            <para>Each entity class must have exactly one ID attribute. The value of this attribute together with the fully-qualified class name uniquely identifies an instance to the entity manager.</para>
            <para>
            ID values can be assigned by the application, or they can be generated by the JPA entity manager. To declare a generated identifier, annotate the field with
            <code>@GeneratedValue</code>
            . To declare an application-assigned identifier, leave off the
            <code>@GeneratedValue</code>
            annotation.
          </para>
            <para>Generated identifier fields must not be initialized or modified by application code. Application-assigned identifier fields must be initialized to a unique value before the entity is persisted by the entity manager, but must not be modified afterward.</para>
         </section>
         <section id="sid-54493688_ErraiJPA-SinglevaluedAttributes">
            <title>Single-valued Attributes</title>
            <para>
            By default, every field of a JPA basic type is a persistent attribute. If a basic type field should not be presistent, mark it with
            <code>transient</code>
            or annotate it with
            <code>@Transient</code>
            .
          </para>
            <para>
            Single-valued attributes of entity types must be annotated with
            <code>@OneToOne</code>
            or
            <code>@ManyToOne</code>
            .
          </para>
            <para>Single-valued types that are neither entity types nor JPA Basic types are not presently supported by Errai JPA. Such attributes must be marked transient.</para>
            <para>Here is an example of an entity with single-valued basic attributes and a single-valued relation to another entity type:</para>
            <informalexample>
               <programlisting language="java">
@Entity
public class Album {

  @GeneratedValue
  @Id
  private Long id;

  private String name;

  @ManyToOne
  private Artist artist;

  private Date releaseDate;

  private Format format;

  public Long getId() { return id; }
  public void setId(Long id) { this.id = id; }

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }

  public Artist getArtist() { return artist; }
  public void setArtist(Artist artist) { this.artist = artist; }

  public Date getReleaseDate() { return releaseDate; }
  public void setReleaseDate(Date releaseDate) { this.releaseDate = releaseDate; }

  public Format getFormat() { return format; }
  public void setFormat(Format format) { this.format = format; }
}
</programlisting>
            </informalexample>
         </section>
         <section id="sid-54493688_ErraiJPA-Plural%28collectionvalued%29Attributes">
            <title>Plural (collection-valued) Attributes</title>
            <para>
            Collection-valued types
            <code>Collection&lt;T&gt;</code>
            ,
            <code>Set&lt;T&gt;</code>
            , and
            <code>List&lt;T&gt;</code>
            are supported. JPA rules require that all access to the collections are done through the collection interface method; never by specific methods on an implementation.
          </para>
            <para>
            The element type of a collection attribute can be a JPA basic type or an entity type. If it is an entity type, the attribute must be annotated with
            <code>@OneToMany</code>
            or
            <code>@ManyToMany</code>
            .
          </para>
            <para>Here is an example of an entity with two plural attributes:</para>
            <informalexample>
               <programlisting language="java">
@Entity
public class Artist {

  @Id
  private Long id;

  private String name;

  // a two-way relationship (albums refer back to artists)
  @OneToMany(mappedBy="artist", cascade=CascadeType.ALL)
  private Set&lt;Album&gt; albums = new HashSet&lt;Album&gt;();

  // a one-way relationship (genres don't reference artists)
  @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
  private Set&lt;Genre&gt; genres = new HashSet&lt;Genre&gt;();

  public Long getId() { return id; }
  public void setId(Long id) { this.id = id; }

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }

  public Set&lt;Album&gt; getAlbums() { return albums; }
  public void setAlbums(Set&lt;Album&gt; albums) { this.albums = albums; }

  public Set&lt;Genre&gt; getGenres() { return genres; }
  public void setGenres(Set&lt;Genre&gt; genres) { this.genres = genres; }
}
</programlisting>
            </informalexample>
         </section>
      </section>
      <section id="sid-54493688_ErraiJPA-EntityLifecycleStates">
         <title>Entity Lifecycle States</title>
         <section id="sid-54493688_ErraiJPA-CascadeRules">
            <title>Cascade Rules</title>
            <para>
            When an entity changes state (more on this later), that state change can be cascaded automatically to related entity instances. By default, no state changes are cascaded to related entities. To request cascading of entity state changes, use the
            <code>cascade</code>
            attribute on any of the relationship quantifiers
            <code>@OneToOne</code>
            ,
            <code>@ManyToOne</code>
            ,
            <code>@OneToMany</code>
            , and
            <code>@ManyToMany</code>
            .
          </para>
            <informaltable>
               <tgroup cols="2">
                  <thead>
                     <row>
                        <entry>
                           <para>CascadeType value</para>
                        </entry>
                        <entry>
                           <para>Description</para>
                        </entry>
                     </row>
                  </thead>
                  <tbody>
                     <row>
                        <entry>
                           <para>
                              <code>PERSIST</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Persist the related entity object(s) when this entity is persisted</para>
                        </entry>
                     </row>
                     <row>
                        <entry>
                           <para>
                              <code>MERGE</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Merge the attributes of the related entity object(s) when this entity is merged</para>
                        </entry>
                     </row>
                     <row>
                        <entry>
                           <para>
                              <code>REMOVE</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Remove the related entity object(s) from persistent storage when this one is removed</para>
                        </entry>
                     </row>
                     <row>
                        <entry>
                           <para>
                              <code>REFRESH</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Not applicable in Errai JPA</para>
                        </entry>
                     </row>
                     <row>
                        <entry>
                           <para>
                              <code>DETACH</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Detach the related entity object(s) from the entity manager when this object is detached</para>
                        </entry>
                     </row>
                     <row>
                        <entry>
                           <para>
                              <code>ALL</code>
                           </para>
                        </entry>
                        <entry>
                           <para>Equivalent to specifying all of the above</para>
                        </entry>
                     </row>
                  </tbody>
               </tgroup>
            </informaltable>
            <para>
            For an example of specifying cascade rules, refer to the
            <code>Artist</code>
            example above. In that example, the cascade type on
            <code>albums</code>
            is
            <code>ALL</code>
            . When a particular
            <code>Artist</code>
            is persisted or removed, detached, etc., all of that artist's albums will also be persisted or removed, or detached correspondingly. However, the cascade rules for
            <code>genres</code>
            are different: we only specify
            <code>PERSIST</code>
            and
            <code>MERGE</code>
            . Because a
            <code>Genre</code>
            instance is reusable and potentially shared between many artists, we do not want to remove or detach these when one artist that references them is removed or detached. However, we still want the convenience of automatic cascading persistence in case we persist an
            <code>Artist</code>
            which references a new, unmanaged
            <code>Genre</code>
            .
          </para>
         </section>
      </section>
      <section id="sid-54493688_ErraiJPA-ObtaininganinstanceofEntityManager">
         <title>Obtaining an instance of EntityManager</title>
         <para>The entity manager provides the means for storing, retrieving, removing, and otherwise affecting the lifecycle state of entity instances.</para>
         <para>To obtain an instance of EntityManager on the client side, use Errai IoC (or CDI) to inject it into any client-side bean:</para>
         <informalexample>
            <programlisting language="java">
@EntryPoint
public class Main {
  @Inject EntityManager em;
}
</programlisting>
         </informalexample>
         <section id="sid-54493688_ErraiJPA-StoringandUpdatingEntities">
            <title>Storing and Updating Entities</title>
            <para>
            To store an entity object in persistent storage, pass that object to the
            <code>EntityManager.persist()</code>
            method. Once this is done, the entity instance transitions from the
            <emphasis role="italics">new</emphasis>
            state to the
            <emphasis role="italics">managed</emphasis>
            state.
          </para>
            <para>
            If the entity references any related entities, these entities must be in the managed state already, or have cascade-on-persist enabled. If neither of these criteria are met, an
            <code>IllegalStateException</code>
            will be thrown.
          </para>
            <para>See an example in the following section.</para>
         </section>
         <section id="sid-54493688_ErraiJPA-FetchingEntitiesbyID">
            <title>Fetching Entities by ID</title>
            <para>
            If you know the unique ID of an entity object, you can use the
            <code>EntityManager.find()</code>
            method to retrieve it from persistent storage. The object returned from the
            <code>find()</code>
            method will be in the managed state.
          </para>
            <para>Example:</para>
            <informalexample>
               <programlisting language="java">
    // make it
    Album album = new Album();
    album.setArtist(null);
    album.setName("Abbey Road");
    album.setReleaseDate(new Date(-8366400000L));

    // store it
    EntityManager em = getEntityManager();
    em.persist(album);
    em.flush();
    em.detach(album);
    assertNotNull(album.getId());

    // fetch it
    Album fetchedAlbum = em.find(Album.class, album.getId());
    assertNotSame(album, fetchedAlbum);
    assertEquals(album.toString(), fetchedAlbum.toString());
</programlisting>
            </informalexample>
         </section>
         <section id="sid-54493688_ErraiJPA-RemovingEntitiesfromPersistentStorage">
            <title>Removing Entities from Persistent Storage</title>
            <para>
            To remove a persistent managed entity, pass it to the
            <code>EntityManager.remove()</code>
            method. As the cascade rules specify, related entities will also be removed recursively.
          </para>
            <para>
            Once an entity has been removed and the entity manager's state has been flushed, the entity object is unmanaged and back in the
            <emphasis role="italics">new</emphasis>
            state.
          </para>
            <section id="sid-54493688_ErraiJPA-ClearingallLocalStorage">
               <title>Clearing all Local Storage</title>
               <para>
              Errai's EntityManager class provides a
              <code>removeAll()</code>
              method which removes everything from the browser's persistent store for the domain of the current webpage.
            </para>
               <para>
              This method is not part of the JPA standard, so you must down-cast your client-side
              <code>EntityManager</code>
              instance to
              <code>ErraiEntityManager</code>
              . Example:
            </para>
               <informalexample>
                  <programlisting language="java">
@EntryPoint
public class Main {

  @Inject EntityManager em;

  void resetJpaStorage() {
    ((ErraiEntityManager) em).removeAll();
  }
}
</programlisting>
               </informalexample>
            </section>
         </section>
         <section id="sid-54493688_ErraiJPA-DetachingEntityInstancesfromtheEntityManager">
            <title>Detaching Entity Instances from the Entity Manager</title>
            <para>
            For every entity instance in the managed state, changes to the attribute values of that entity are persisted to local storage whenever the entity manager is flushed. To prevent this automatic updating from happening, you can
            <emphasis role="italics">detach</emphasis>
            an entity from the entity manager. When an instance is detached, it is not deleted. All information about it remains in persistent storage. The next time that entity is retrieved, the entity manager will create a new and separate managed instance for it.
          </para>
            <para>
            To detach one particular object along with all related objects whose cascade rules say so, call
            <code>EntityManager.detach()</code>
            and pass in that object.
          </para>
            <para>
            To detach all objects from the entity manager at once, call
            <code>EntityManager.detachAll()</code>
            .
          </para>
         </section>
         <section id="sid-54493688_ErraiJPA-TestingifanEntityisintheManagedState">
            <title>Testing if an Entity is in the Managed State</title>
            <para>
            To check if a given object is presently managed by the entity manager, call
            <code>EntityManager.contains()</code>
            and pass in the object of interest.
          </para>
         </section>
      </section>
      <section id="sid-54493688_ErraiJPA-NamedQueries">
         <title>Named Queries</title>
         <para>
          To retrieve one or more entities that match a set of criteria, Errai JPA allows the use of JPA
          <emphasis role="italics">named queries</emphasis>
          . Named queries are declared in annotations on entity classes.
        </para>
         <section id="sid-54493688_ErraiJPA-DeclaringNamedQueries">
            <title>Declaring Named Queries</title>
            <para>Queries in JPA are written in the JPQL language. As of Errai 2.1, Errai JPA does not support all JPQL features. Most importantly, implicit and explicit joins in queries are not yet supported. Queries of the following form generally work:</para>
            <informalexample>
               <programlisting language="java">
SELECT et FROM EntityType et WHERE [expression with constants, named parameters and attributes of et] ORDER BY et.attr1 [ASC|DESC], et.attr2 [ASC|DESC]
</programlisting>
            </informalexample>
            <para>Here is how to declare a JPQL query on an entity:</para>
            <informalexample>
               <programlisting language="java">
@NamedQuery(name="selectAlbumByName", query="SELECT a FROM Album a WHERE a.name=:name")
@Entity
public class Album {
  ... same as before ...
}
</programlisting>
            </informalexample>
            <para>
            To declare more than one query on the same entity, wrap the
            <code>@NamedQuery</code>
            annotations in
            <code>@NamedQueries</code>
            like this:
          </para>
            <informalexample>
               <programlisting language="java">
@NamedQueries({
  @NamedQuery(name="selectAlbumByName", query="SELECT a FROM Album a WHERE a.name = :name"),
  @NamedQuery(name="selectAlbumsAfter", query="SELECT a FROM Album a WHERE a.releaseDate &gt;= :startDate")
})
@Entity
public class Album {
  ... same as before ...
}
</programlisting>
            </informalexample>
         </section>
         <section id="sid-54493688_ErraiJPA-ExecutingNamedQueries">
            <title>Executing Named Queries</title>
            <para>
            To execute a named query, retrieve it by name and result type from the entity manager, set the values of its parameters (if any), and then call one of the execution methods
            <code>getSingleResult()</code>
            or
            <code>getResultList()</code>
            .
          </para>
            <para>Example:</para>
            <informalexample>
               <programlisting language="java">
    TypedQuery&lt;Album&gt; q = em.createNamedQuery("selectAlbumByName", Album.class);
    q.setParameter("name", "Let It Be");
    List&lt;Album&gt; fetchedAlbums = q.getResultList();
</programlisting>
            </informalexample>
         </section>
      </section>
      <section id="sid-54493688_ErraiJPA-EntityLifecycleEvents">
         <title>Entity Lifecycle Events</title>
         <para>To receive a notification when an entity instance transitions from one lifecycle state to another, use an entity lifecycle listener.</para>
         <para>These annotations can be applied to methods in order to receive notifications at certain points in an entity's lifecycle. These events are delivered for direct operations initiated on the EntityManager as well as operations that happen due to cascade rules.</para>
         <informaltable>
            <tgroup cols="2">
               <thead>
                  <row>
                     <entry>
                        <para>Annotation</para>
                     </entry>
                     <entry>
                        <para>Meaning</para>
                     </entry>
                  </row>
               </thead>
               <tbody>
                  <row>
                     <entry>
                        <para>
                           <code>@PrePersist</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity is about to be persisted or merged into the entity manager.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PostPersist</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity has just been persisted or merged into the entity manager.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PreUpdate</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity's state is about to be captured into the browser's localStorage.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PostUpdate</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity's state has just been captured into the browser's localStorage.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PreRemove</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity is about to be removed from persistent storage.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PostRemove</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity has just been removed from persistent storage.</para>
                     </entry>
                  </row>
                  <row>
                     <entry>
                        <para>
                           <code>@PostLoad</code>
                        </para>
                     </entry>
                     <entry>
                        <para>The entity's state has just been retrieved from the browser's localStorage.</para>
                     </entry>
                  </row>
               </tbody>
            </tgroup>
         </informaltable>
         <para>JPA lifecycle event annotations can be placed on methods in the entity type itself, or on a method of any type with a public no-args constructor.</para>
         <para>To receive lifecycle event notifications directly on the affected entity instance, create a no-args method on the entity class and annotate it with one or more of the lifecycle annotations in the above table.</para>
         <para>For example, here is a variant of the Album class where instances receive notification right after they are loaded from persistent storage:</para>
         <informalexample>
            <programlisting language="java">
@Entity
public class Album {

  ... same as before ...

  @PostLoad
  public void postLoad() {
    System.out.println("Album " + getName() + " was just loaded into the entity manager");
  }
}
</programlisting>
         </informalexample>
         <para>
          To receive lifecycle methods in a different class, declare a method that takes one parameter of the entity type and annotate it with the desired lifecycle annotations. Then name that class in the
          <code>@EntityListeners</code>
          annotation on the entity type.
        </para>
         <para>The following example produces the same results as the previous example:</para>
         <informalexample>
            <programlisting language="java">
@Entity
@EntityListeners(StandaloneLifecycleListener.class)
public class Album {

  ... same as always ...

}

public class StandaloneLifecycleListener {

  @PostLoad
  public void albumLoaded(Album a) {
  public void postLoad() {
    System.out.println("Album " + a.getName() + " was just loaded into the entity manager");
  }
}
</programlisting>
         </informalexample>
      </section>
      <section id="sid-54493688_ErraiJPA-JPAMetamodel">
         <title>JPA Metamodel</title>
         <para>Errai captures structural information about entity types at compile time and makes them available in the GWT runtime environment. The JPA metamodel includes methods for enumerating all known entity types and enumerating the singular and plural attributes of those types. Errai extends the JPA 2.0 Metamodel by providing methods that can create new instances of entity classes, and read and write attribute values of existing entity instances.</para>
         <para>As an example of what is possible, this functionality could be used to create a reusable UI widget that can present an editable table of any JPA entity type.</para>
         <para>
          To access the JPA Metamodel, call the
          <code>EntityManager.getMetamodel()</code>
          method. For details on what can be done with the stock JPA metamodel, see the API's javadoc or consult the JPA specification.
        </para>
         <section id="sid-54493688_ErraiJPA-ErraiExtensionstoJPAMetamodelAPI">
            <title>Errai Extensions to JPA Metamodel API</title>
            <para>
            Wherever you obtain an instance of
            <code>SingularAttribute</code>
            from the metamodel API, you can down-cast it to
            <code>ErraiSingularAttribute</code>
            . Likewise, you can down-cast any
            <code>PluralAttribute</code>
            to
            <code>ErraiPluralAttribute</code>
            .
          </para>
            <para>
            In either case, you can read the value of an arbitrary attribute by calling
            <code>ErraiAttribute.get()</code>
            and passing in the entity instance. You can set any attribute's value by calling
            <code>ErraiAttribute.set()</code>
            , passing in the entity instance and the new value.
          </para>
            <para>
            In addition to
            <code>get()</code>
            and
            <code>set()</code>
            ,
            <code>ErraiPluralAttribute</code>
            also has the
            <code>createEmptyCollection()</code>
            method, which creates an empty collection of the correct interface type for the given attribute.
          </para>
         </section>
      </section>
      <section id="sid-54493688_ErraiJPA-JPAFeaturesNotImplementedinErrai2.1">
         <title>JPA Features Not Implemented in Errai 2.1</title>
         <para>The following features are not yet implemented, but could conceivably be implemented in a future Errai JPA release:</para>
         <itemizedlist>
            <listitem>
               <para>
              Many
              <code>persistence.xml</code>
              settings are not honoured; need to use annotations for these
            </para>
            </listitem>
            <listitem>
               <para>Flush modes other than immediate</para>
            </listitem>
            <listitem>
               <para>Transactions, including EntityManager.getTransaction()</para>
            </listitem>
            <listitem>
               <para>More than one persistence context</para>
            </listitem>
            <listitem>
               <para>In named queries:</para>
               <itemizedlist>
                  <listitem>
                     <para>
                  Joins and nested attribute paths (
                  <code>a.b.c</code>
                  ) do not yet work, although single-step attribute paths (
                  <code>a.b</code>
                  ) do.
                </para>
                  </listitem>
                  <listitem>
                     <para>
                  The
                  <code>SELECT</code>
                  clause must specify exactly one entity type. Selection of individual attributes is not yet implemented.
                </para>
                  </listitem>
               </itemizedlist>
            </listitem>
            <listitem>
               <para>Embedded collections</para>
            </listitem>
            <listitem>
               <para>Compound identifiers (presently, only basic types are supported for entity IDs)</para>
            </listitem>
            <listitem>
               <para>Polymorphic relations (eg. relationship to a collection of a base entity type)</para>
            </listitem>
            <listitem>
               <para>
                  <code>EntityManager.merge()</code>
               </para>
            </listitem>
            <listitem>
               <para>Criteria Queries</para>
               <itemizedlist>
                  <listitem>
                     <para>The generated static Metamodel</para>
                  </listitem>
               </itemizedlist>
            </listitem>
            <listitem>
               <para>
              The
              <code>@PersistenceContext</code>
              annotation currently has no effect in client-side code (use
              <code>@Inject</code>
              instead)
            </para>
            </listitem>
         </itemizedlist>
         <para>The following may never be implemented due to limitations and restrictions in the GWT client-side environment:</para>
         <itemizedlist>
            <listitem>
               <para>
                  <code>EntityManager.createQuery(String, ...)</code>
              (that is, unnamed queries) are impractical because JPQL queries are parsed at compile time, not in the browser.
            </para>
            </listitem>
            <listitem>
               <para>
                  <code>EntityManager.createNativeQuery(String, ...)</code>
              don't make sense because the underlying database is just a hash table. It does not have a query language.
            </para>
            </listitem>
            <listitem>
               <para>
                  <code>EntityManager.refresh()</code>
              is not implemented, but since nothing else updates the underlying database, this should not pose a problem.
            </para>
            </listitem>
            <listitem>
               <para>
              Persistent attributes of type
              <code>java.util.Calendar</code>
              because the
              <code>Calendar</code>
              class is not in GWT's JRE emulation library.
            </para>
            </listitem>
         </itemizedlist>
      </section>
      <section id="sid-54493688_ErraiJPA-OtherCaveatsforErrai2.1JPA">
         <title>Other Caveats for Errai 2.1 JPA</title>
         <para>We hope to remedy these shortcomings in a future release.</para>
         <itemizedlist>
            <listitem>
               <para>
              The
              <code>persistence.xml</code>
              file is not optional. It must list all the entity types that Errai should know about
            </para>
            </listitem>
            <listitem>
               <para>In Dev Mode, changes to entity classes are not discovered on page refresh. You need to restart Dev Mode.</para>
            </listitem>
            <listitem>
               <para>The local data stored in the browser is not encrypted</para>
            </listitem>
         </itemizedlist>
      </section>
   </section>
</chapter>