Overview
Note
| Using JPAContainer is no longer recommended. While it works for simple data models, it is not as easy to use as it should be. It also has architectural weaknesses and performance issues that cause problems in building more complex applications. Instead, we recommend using JPA directly, while hiding it from your UI logic behind a DAO or service class. In UI code, you should mainly handle beans and collections of beans, bound to a BeanItemContainer. You should also note the Viritin add-on, which provides data binding features that help with JPA. |
Vaadin JPAContainer add-on makes it possible to bind user interface components to a database easily using the Java Persistence API (JPA). It is an implementation of the Container interface described in "Collecting Items in Containers". It supports a typical three-layer application architecture with an intermediate domain model between the user interface and the data access layer.
The role of Java Persistence API is to handle persisting the domain model in the database. The database is typically a relational database. Vaadin JPAContainer binds the user interface components to the domain model and handles database access with JPA transparently.
JPA is really just an API definition and has many alternative implementations. Vaadin JPAContainer supports especially EclipseLink, which is the reference implementation of JPA, and Hibernate. Any other compliant implementation should work just as well. The architecture of an application using JPAContainer is shown in JPAContainer Architecture.
Vaadin JPAContainer also plays together with the Vaadin support for Java Bean Validation (JSR 303).
Java Persistence API
Java Persistence API (JPA) is an API for object-relational mapping (ORM) of Java objects to a relational database. In JPA and entity-relationship modeling in general, a Java class is considered an entity. Class (or entity) instances correspond with a row in a database table and member variables of a class with columns. Entities can also have relationships with other entities.
The object-relational mapping is illustrated in Object-Relational Mapping with two entities with a one-to-many relationship.
The entity relationships are declared with metadata. With Vaadin JPAContainer, you provide the metadata with annotations in the entity classes. The JPA implementation uses reflection to read the annotations and defines a database model automatically from the class definitions. Definition of the domain model and the annotations are described in "Persistence Metadata".
The main interface in JPA is the EntityManager, which allows making different kinds of queries either with the Java Persistence Query Language (JPQL), native SQL, or the Criteria API in JPA 2.0. You can always use the interface directly as well, using Vaadin JPAContainer only for binding the data to the user interface.
Vaadin JPAContainer supports JPA 2.0 (JSR 317). It is available under the Apache License 2.0.
JPAContainer Concepts
The JPAContainer is an implementation of the Vaadin Container interface that you can bind to user interface components such as Table, ComboBox, etc.
The data access to the persistent entities is handled with a entity provider, as defined in the EntityProvider interface. JPAContainer provides a number of different entity providers for different use cases and optimizations. The built-in providers are described in "Entity Providers".
JPAContainer is by default unbuffered, so that any entity property changes are written immediately to the database when you call setValue() for a property, or when a user edits a bound field. A container can be set as buffered, so that changes are written on calling commit(). Buffering can be done both at item level, such as when updating item property values, or at container level, such as when adding or deleting items. Only batchable containers, that is, containers with a batchable entity provider, can be buffered. Note that buffering is recommended for situations where two users could update the same entity simultaneously, and when this would be a problem. In an unbuffered container, the entity is refreshed before writing an update, so the last write wins and a conflicting simultaneous update written before it is lost. A buffered container throws an OptimisticLockException when two users edit the same item (an unbuffered container never throws it), thereby allowing to handle the situation with application logic.