summaryrefslogtreecommitdiffstats
path: root/documentation/jpacontainer/jpacontainer-domain-model.asciidoc
diff options
context:
space:
mode:
authorelmot <elmot@vaadin.com>2015-09-25 16:40:44 +0300
committerelmot <elmot@vaadin.com>2015-09-25 16:40:44 +0300
commita1b265c318dbda4a213cec930785b81e4c0f7d2b (patch)
treeb149daf5a4f50b4f6446c906047cf86495fe0433 /documentation/jpacontainer/jpacontainer-domain-model.asciidoc
parentb9743a48a1bd0394f19c54ee938c6395a80f3cd8 (diff)
downloadvaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.tar.gz
vaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.zip
Framework documentation IN
Change-Id: I767477c1fc3745f9e1f58075fe30c9ac8da63581
Diffstat (limited to 'documentation/jpacontainer/jpacontainer-domain-model.asciidoc')
-rw-r--r--documentation/jpacontainer/jpacontainer-domain-model.asciidoc265
1 files changed, 265 insertions, 0 deletions
diff --git a/documentation/jpacontainer/jpacontainer-domain-model.asciidoc b/documentation/jpacontainer/jpacontainer-domain-model.asciidoc
new file mode 100644
index 0000000000..4d5fe482bf
--- /dev/null
+++ b/documentation/jpacontainer/jpacontainer-domain-model.asciidoc
@@ -0,0 +1,265 @@
+---
+title: Defining a Domain Model
+order: 3
+layout: page
+---
+
+[[jpacontainer.domain-model]]
+= Defining a Domain Model
+
+Developing a persistent application begins with defining a domain model. A
+domain model consists of a number of entities (classes) and relationships
+between them.
+
+<<figure.jpacontainer.domain-model>> illustrates a simple domain model as a UML
+class diagram. It has two entities: [classname]#Country# and
+[classname]#Person#. They have a "country has persons" relationship. This is a
+__one-to-many relationship__ with one country having many persons, each of which
+belongs to just one country.
+
+[[figure.jpacontainer.domain-model]]
+.A Domain Model
+image::img/domain-model-hi.png[]
+
+Realized in Java, the classes are as follows:
+
+
+----
+public class Country {
+ private Long id;
+ private String name;
+ private Set<Person> persons;
+
+ ... setters and getters ...
+}
+
+public class Person {
+ private Long id;
+ private String name;
+ private Integer age;
+ private Country country;
+
+ ... setters and getters ...
+}
+----
+
+You should make the classes proper beans by defining a default constructor and
+implementing the [interfacename]#Serializable# interface. A default constructor
+is required by the JPA entity manager for instantiating entities. Having the
+classes serializable is not required but often useful for other reasons.
+
+After you have a basic domain model, you need to define the entity relationship
+metadata by annotating the classes.
+
+[[jpacontainer.domain-model.annotation]]
+== Persistence Metadata
+
+The entity relationships are defined with metadata. The metadata can be defined
+in an XML metadata file or with Java annotations defined in the
+[package]#javax.persistence# package. With Vaadin JPAContainer, you need to
+provide the metadata as annotations.
+
+For example, if we look at the Person class in the JPAContainer AddressBook
+Demo, we define various database-related metadata for the member variables of a
+class:
+
+
+----
+@Entity
+public class Person {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String name;
+ private Integer age;
+
+ @ManyToOne
+ private Country country;
+----
+
+The JPA implementation uses reflection to read the annotations and defines a
+database model automatically from the class definitions.
+
+Let us look at some of the basic JPA metadata annotations. The annotations are
+defined in the [package]#javax.persistence# package. Please refer to JPA
+reference documentation for the complete list of possible annotations.
+
+[[jpacontainer.domain-model.metadata.entity]]
+=== Annotation: [literal]#++@Entity++#
+
+Each class that is enabled as a persistent entity must have the
+[literal]#++@Entity++# annotation.
+
+
+----
+@Entity
+public class Country {
+----
+
+
+[[jpacontainer.domain-model.annotation.id]]
+=== Annotation: [literal]#++@Id++#
+
+Entities must have an identifier that is used as the primary key for the table.
+It is used for various purposes in database queries, most commonly for joining
+tables.
+
+
+----
+@Id
+@GeneratedValue(strategy = GenerationType.AUTO)
+private Long id;
+----
+
+The identifier is generated automatically in the database. The strategy for
+generating the identifier is defined with the [literal]#++@GeneratedValue++#
+annotation. Any generation type should work.
+
+
+[[jpacontainer.domain-model.annotation.onetoone]]
+=== Annotation: [literal]#++@OneToOne++#
+
+The [literal]#++@OneToOne++# annotation describes a one-to-one relationship
+where each entity of one type is associated with exactly one entity of another
+type. For example, the postal address of a person could be given as such.
+
+
+----
+@OneToOne
+private Address address;
+----
+
+When using the JPAContainer [classname]#FieldFactory# to automatically create
+fields for a form, the [literal]#++@OneToOne++# relationship generates a nested
+[classname]#Form# to edit the data. See
+<<dummy/../../../framework/jpacontainer/jpacontainer-fieldfactory#jpacontainer.fieldfactory,"Automatic
+Form Generation">> for more details.
+
+
+[[jpacontainer.domain-model.annotation.embedded]]
+=== Annotation: [literal]#++@Embedded++#
+
+Just as with the [literal]#++@OneToOne++# annotation, [literal]#++@Embedded++#
+describes a one-to-one relationship, but says that the referenced entity should
+be stored as columns in the same table as the referencing entity.
+
+
+----
+@Embedded
+private Address address;
+----
+
+The referenced entity class must have [literal]#++@Embeddable++# annotation.
+
+The JPAContainer [classname]#FieldFactory# generates a nested [classname]#Form#
+for [literal]#++@Embedded++#, just as with [literal]#++@OneToOne++#.
+
+
+[[jpacontainer.domain-model.annotation.onetomany]]
+=== Annotation: [literal]#++@OneToMany++#
+
+The [classname]#Country# entity in the domain model has a __one-to-many__
+relationship with the [classname]#Person# entity ("country has persons"). This
+relationship is represented with the [literal]#++@OneToMany++# annotation. The
+[parameter]#mappedBy# parameter names the corresponding back-reference in the
+[classname]#Person# entity.
+
+
+----
+@OneToMany(mappedBy = "country")
+private Set<Person> persons;
+----
+
+When using the JPAContainer [classname]#FieldFactory# to automatically create
+fields for a form, the [literal]#++@OneToMany++# relationship generates a
+[classname]#MasterDetailEditor# for editing the items. See
+<<dummy/../../../framework/jpacontainer/jpacontainer-fieldfactory#jpacontainer.fieldfactory,"Automatic
+Form Generation">> for more details.
+
+
+[[jpacontainer.domain-model.annotation.elementcollection]]
+=== Annotation: [literal]#++@ElementCollection++#
+
+The [literal]#++@ElementCollection++# annotation can be used for one-to-many
+relationships to a collection of basic values such as [classname]#String# or
+[classname]#Integer#, or to entities annotated as [literal]#++@Embeddable++#.
+The referenced entities are stored in a separate table defined with a
+[literal]#++@CollectionTable++# annotation.
+
+
+----
+@ElementCollection
+@CollectionTable(
+ name="OLDPEOPLE",
+ joinColumns=@JoinColumn(name="COUNTRY_ID"))
+private Set<Person> persons;
+----
+
+JPAContainer [classname]#FieldFactory# generates a
+[classname]#MasterDetailEditor# for the [literal]#++@ElementCollection++#
+relationship, just as with [literal]#++@OneToMany++#.
+
+
+[[jpacontainer.domain-model.annotation.manytoone]]
+=== Annotation: [literal]#++@ManyToOne++#
+
+Many people can live in the same country. This would be represented with the
+[literal]#++@ManyToOne++# annotation in the [classname]#Person# class.
+
+
+----
+@ManyToOne
+private Country country;
+----
+
+JPAContainer [classname]#FieldFactory# generates a [classname]#NativeSelect# for
+selecting an item from the collection. You can do so yourself as well in a
+custom field factory. Doing so you need to pay notice not to confuse the
+container between the referenced entity and its ID, which could even result in
+insertion of false entities in the database in some cases. You can handle
+conversion between an entity and the entity ID using the
+[classname]#SingleSelectConverter# as follows:
+
+
+----
+
+@Override
+public <T extends Field> T createField(Class<?> dataType,
+ Class<T> fieldType) {
+ if (dataType == Country.class) {
+ JPAContainer<Country> countries =
+ JPAContainerFactory.make(Country.class, "mypunit");
+ ComboBox cb = new ComboBox(null, countries);
+ cb.setConverter(new SingleSelectConverter<Country>(cb));
+ return (T) cb;
+ }
+ return super.createField(dataType, fieldType);
+}
+----
+
+The JPAContainer [classname]#FieldFactory# uses the translator internally, so
+using it also avoids the problem.
+
+
+[[jpacontainer.domain-model.annotation.transient]]
+=== Annotation: [literal]#++@Transient++#
+
+JPA assumes that all entity properties are persisted. Properties that should not
+be persisted should be marked as transient with the [literal]#++@Transient++#
+annotation.
+
+
+----
+@Transient
+private Boolean superDepartment;
+...
+@Transient
+public String getHierarchicalName() {
+...
+----
+
+
+
+
+