JBoss.orgCommunity Documentation

Chapter 8. Errai JPA

8.1. Getting Started
8.1.1. Compile-time dependency
8.1.2. GWT Module Descriptor
8.1.3. INF/persistence.xml
8.1.4. Declaring an Entity Class
8.1.5. Entity Lifecycle States
8.1.6. Obtaining an instance of EntityManager
8.1.7. Named Queries
8.1.8. Entity Lifecycle Events
8.1.9. JPA Metamodel
8.1.10. JPA Features Not Implemented in Errai 2.1
8.1.11. Other Caveats for Errai 2.1 JPA

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.

Errai JPA implements the following subset of JPA 2.0:

It's all client-side

Errai JPA is a declarative, typesafe interface to the web browser's localStorage object. As such it is a client-side implementation of JPA. Objects are stored and fetched from the browser's local storage, not from the JPA provider on the server side.

Classes whose instances can be stored and retrieved by JPA are called entities . To declare a class as a JPA entity, annotate it with @Entity .

JPA requires that entity classes conform to a set of rules. These are:

Here is an example of a valid entity class with an ID attribute ( id ) and a String-valued persistent attribute ( name ):

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 cascade attribute on any of the relationship quantifiers @OneToOne , @ManyToOne , @OneToMany , and @ManyToMany .

CascadeType value

Description

PERSIST

Persist the related entity object(s) when this entity is persisted

MERGE

Merge the attributes of the related entity object(s) when this entity is merged

REMOVE

Remove the related entity object(s) from persistent storage when this one is removed

REFRESH

Not applicable in Errai JPA

DETACH

Detach the related entity object(s) from the entity manager when this object is detached

ALL

Equivalent to specifying all of the above

For an example of specifying cascade rules, refer to the Artist example above. In that example, the cascade type on albums is ALL . When a particular Artist 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 genres are different: we only specify PERSIST and MERGE . Because a Genre 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 Artist which references a new, unmanaged Genre .

The entity manager provides the means for storing, retrieving, removing, and otherwise affecting the lifecycle state of entity instances.

To obtain an instance of EntityManager on the client side, use Errai IoC (or CDI) to inject it into any client-side bean:

To retrieve one or more entities that match a set of criteria, Errai JPA allows the use of JPA named queries . Named queries are declared in annotations on entity classes.

To receive a notification when an entity instance transitions from one lifecycle state to another, use an entity lifecycle listener.

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.

Annotation

Meaning

@PrePersist

The entity is about to be persisted or merged into the entity manager.

@PostPersist

The entity has just been persisted or merged into the entity manager.

@PreUpdate

The entity's state is about to be captured into the browser's localStorage.

@PostUpdate

The entity's state has just been captured into the browser's localStorage.

@PreRemove

The entity is about to be removed from persistent storage.

@PostRemove

The entity has just been removed from persistent storage.

@PostLoad

The entity's state has just been retrieved from the browser's localStorage.

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.

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.

For example, here is a variant of the Album class where instances receive notification right after they are loaded from persistent storage:

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 @EntityListeners annotation on the entity type.

The following example produces the same results as the previous example:

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.

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.

To access the JPA Metamodel, call the EntityManager.getMetamodel() method. For details on what can be done with the stock JPA metamodel, see the API's javadoc or consult the JPA specification.

The following features are not yet implemented, but could conceivably be implemented in a future Errai JPA release:

The following may never be implemented due to limitations and restrictions in the GWT client-side environment: