Browse Source

Remove jpacontainer section from the docs. (#8047)

* Remove jpacontainer section from the docs.
tags/8.0.0.beta1
Denis 7 years ago
parent
commit
03f0e0f31b
29 changed files with 2 additions and 9000 deletions
  1. 0
    7
      documentation/advanced/advanced-architecture.asciidoc
  2. 2
    0
      documentation/components/components-calendar.asciidoc
  3. 0
    25
      documentation/jpacontainer/chapter-jpacontainer.asciidoc
  4. BIN
      documentation/jpacontainer/img/detailed-architecture-hi.png
  5. BIN
      documentation/jpacontainer/img/detailed-architecture-lo.png
  6. BIN
      documentation/jpacontainer/img/domain-model-hi.png
  7. BIN
      documentation/jpacontainer/img/domain-model-lo.png
  8. BIN
      documentation/jpacontainer/img/fieldfactory-form.png
  9. BIN
      documentation/jpacontainer/img/jpa-mapping-graphic-hi.png
  10. BIN
      documentation/jpacontainer/img/jpa-mapping-graphic-lo.png
  11. BIN
      documentation/jpacontainer/img/nested-properties.png
  12. BIN
      documentation/jpacontainer/img/table-comets.png
  13. BIN
      documentation/jpacontainer/img/three-layer-architecture-hi.png
  14. BIN
      documentation/jpacontainer/img/three-layer-architecture-lo.png
  15. 0
    265
      documentation/jpacontainer/jpacontainer-domain-model.asciidoc
  16. 0
    225
      documentation/jpacontainer/jpacontainer-entityprovider.asciidoc
  17. 0
    151
      documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc
  18. 0
    95
      documentation/jpacontainer/jpacontainer-filtering-criteria-api.asciidoc
  19. 0
    45
      documentation/jpacontainer/jpacontainer-filtering.asciidoc
  20. 0
    180
      documentation/jpacontainer/jpacontainer-hibernate.asciidoc
  21. 0
    305
      documentation/jpacontainer/jpacontainer-installation.asciidoc
  22. 0
    124
      documentation/jpacontainer/jpacontainer-overview.asciidoc
  23. 0
    386
      documentation/jpacontainer/jpacontainer-usage.asciidoc
  24. 0
    1165
      documentation/jpacontainer/original-drawings/detailed-architecture-web.svg
  25. 0
    1088
      documentation/jpacontainer/original-drawings/detailed-architecture.svg
  26. 0
    938
      documentation/jpacontainer/original-drawings/domain-model.svg
  27. 0
    1504
      documentation/jpacontainer/original-drawings/jpa-mapping-graphic.svg
  28. 0
    1428
      documentation/jpacontainer/original-drawings/jpa-mapping.svg
  29. 0
    1069
      documentation/jpacontainer/original-drawings/three-layer-architecture.svg

+ 0
- 7
documentation/advanced/advanced-architecture.asciidoc View File

@@ -42,13 +42,6 @@ domain layer, offering the domain logic as a service, which can be used by the
user interface layer, as well as for other uses. In Java EE development,
Enterprise JavaBeans (EJBs) are typically used for building this layer.

An __infrastructure layer__ (or __data access layer__) is often distinguished
from the data store layer, with a purpose to abstract the data store. For
example, it could involve a persistence solution such as JPA and an EJB
container. This layer becomes relevant with Vaadin when binding Vaadin
components to data with the JPAContainer, as described in
<<dummy/../../../framework/jpacontainer/jpacontainer-overview.asciidoc#jpacontainer.overview,"Vaadin
JPAContainer">>.


[[advanced.architecture.mvp]]

+ 2
- 0
documentation/components/components-calendar.asciidoc View File

@@ -7,6 +7,8 @@ layout: page
[[components.calendar]]
= [classname]#Calendar#

*_This section has not yet been updated for Vaadin Framework 8._*

ifdef::web[]
[.sampler]
image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/data-input/dates/dates-calendar"]

+ 0
- 25
documentation/jpacontainer/chapter-jpacontainer.asciidoc View File

@@ -1,25 +0,0 @@
[[jpacontainer]]
== Vaadin JPAContainer

((("JPAContainer", id="term.jpacontainer", range="startofrange")))

This chapter describes the use of the Vaadin JPAContainer add-on.

include::jpacontainer-overview.asciidoc[leveloffset=+2]

include::jpacontainer-installation.asciidoc[leveloffset=+2]

include::jpacontainer-domain-model.asciidoc[leveloffset=+2]

include::jpacontainer-usage.asciidoc[leveloffset=+2]

include::jpacontainer-entityprovider.asciidoc[leveloffset=+2]

include::jpacontainer-filtering.asciidoc[leveloffset=+2]

include::jpacontainer-filtering-criteria-api.asciidoc[leveloffset=+2]

include::jpacontainer-fieldfactory.asciidoc[leveloffset=+2]

include::jpacontainer-hibernate.asciidoc[leveloffset=+2]
(((range="endofrange", startref="term.jpacontainer")))

BIN
documentation/jpacontainer/img/detailed-architecture-hi.png View File


BIN
documentation/jpacontainer/img/detailed-architecture-lo.png View File


BIN
documentation/jpacontainer/img/domain-model-hi.png View File


BIN
documentation/jpacontainer/img/domain-model-lo.png View File


BIN
documentation/jpacontainer/img/fieldfactory-form.png View File


BIN
documentation/jpacontainer/img/jpa-mapping-graphic-hi.png View File


BIN
documentation/jpacontainer/img/jpa-mapping-graphic-lo.png View File


BIN
documentation/jpacontainer/img/nested-properties.png View File


BIN
documentation/jpacontainer/img/table-comets.png View File


BIN
documentation/jpacontainer/img/three-layer-architecture-hi.png View File


BIN
documentation/jpacontainer/img/three-layer-architecture-lo.png View File


+ 0
- 265
documentation/jpacontainer/jpacontainer-domain-model.asciidoc View File

@@ -1,265 +0,0 @@
---
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() {
...
----






+ 0
- 225
documentation/jpacontainer/jpacontainer-entityprovider.asciidoc View File

@@ -1,225 +0,0 @@
---
title: Entity Providers
order: 5
layout: page
---

[[jpacontainer.entityprovider]]
= Entity Providers

Entity providers provide access to entities persisted in a data store. They are
essentially wrappers over a JPA entity manager, adding optimizations and other
features important when binding persistent data to a user interface.

The choice and use of entity providers is largely invisible if you create your
[classname]#JPAContainer# instances with the [classname]#JPAContainerFactory#,
which hides such details.

JPAContainer entity providers can be customized, which is necessary for some
purposes. Entity providers can be Enterprise JavaBeans (EJBs), which is useful
when you use them in a Java EE application server.

[[jpacontainer.entityprovider.built-in]]
== Built-In Entity Providers

JPAContainer includes various kinds of built-in entity providers: caching and
non-caching, read-write and read-only, and batchable.

__Caching__ is useful for performance, but takes some memory for the cache and
makes the provider stateful. __Batching__, that is, running updates in larger
batches, can also enhance performance and be used together with caching. It is
stateless, but doing updates is a bit more complex than otherwise.

Using a __read-only__ container is preferable if read-write capability is not
needed.

All built-in providers are __local__ in the sense that they provide access to
entities using a local JPA entity manager.

The [classname]#CachingMutableLocalEntityProvider# is usually recommended as the
first choise for read-write access and [classname]#CachingLocalEntityProvider#
for read-only access.

=== [classname]#LocalEntityProvider#

A read-only, lazy loading entity provider that does not perform caching and
reads its data directly from an entity manager.

You can create the provider with [methodname]#makeNonCachedReadOnly()# method in
[classname]#JPAContainerFactory#.


=== [classname]#MutableLocalEntityProvider#

Extends [classname]#LocalEntityProvider# with write support. All changes are
directly sent to the entity manager.

Transactions can be handled either internally by the provider, which is the
default, or by the container. In the latter case, you can extend the class and
annotate it, for example, as described in
<<jpacontainer.entityprovider.built-in>>.

The provider can notify about updates to entities through the
[interfacename]#EntityProviderChangeNotifier# interface.


=== [classname]#BatchableLocalEntityProvider#

A simple non-caching implementation of the
[interfacename]#BatchableEntityProvider# interface. It extends
[classname]#MutableLocalEntityProvider# and simply passes itself to the
[methodname]#batchUpdate()# callback method. This will work properly if the
entities do not contain any references to other entities that are managed by the
same container.


=== [classname]#CachingLocalEntityProvider#

A read-only, lazy loading entity provider that caches both entities and query
results for different filter/sortBy combinations. When the cache gets full, the
oldest entries in the cache are removed. The maximum number of entities and
entity IDs to cache for each filter/sortBy combination can be configured in the
provider. The cache can also be manually flushed. When the cache grows full, the
oldest items are removed.

You can create the provider with [methodname]#makeReadOnly()# method in
[classname]#JPAContainerFactory#.


=== [classname]#CachingMutableLocalEntityProvider#

Just like [classname]#CachingLocalEntityProvider#, but with read-write access.
For read access, caching works just like in the read-only provider. When an
entity is added or updated, the cache is flushed in order to make sure the added
or updated entity shows up correctly when using filters and/or sorting. When an
entity is removed, only the filter/sortBy-caches that actually contain the item
are flushed.

This is perhaps the most commonly entity provider that you should consider using
for most tasks. You can create it with the [methodname]#make()# method in
[classname]#JPAContainerFactory#.


=== [classname]#CachingBatchableLocalEntityProvider#

This provider supports making updates in __batches__. You need to implement a
[interfacename]#BatchUpdateCallback# that does all the updates and execute the
batch by calling [methodname]#batchUpdate()# on the provider.

The provider is an extension of the
[classname]#CachingMutableLocalEntityProvider# that implements the
[interfacename]#BatchableEntityProvider# interface. This will work properly if
the entities do not contain any references to other entities that are managed by
the same container.

You can create the provider with [methodname]#makeBatchable()# method in
[classname]#JPAContainerFactory#.



[[jpacontainer.entityprovider.jndi]]
== Using JNDI Entity Providers in JEE6 Environment

JPAContainer 2.0 introduced a new set of entity providers specifically for
working in a [literal]#++JEE6++# environment. In a JEE environment, you should
use an entity manager provided by the application server and, usually,
[literal]#++JTA++# transactions instead of transactions provided by JPA. Entity
providers in [package]#com.vaadin.addon.jpacontainer.provider.jndijta# package
work mostly the same way as the normal providers discussed earlier, but use JNDI
lookups to get reference to an [interfacename]#EntityManager# and to a JTA
transaction.

The JNDI providers work with almost no special configuration at all. The
[classname]#JPAContainerFactory# has factory methods for creating various JNDI
provider types. The only thing that you commonly need to do is to expose the
[interfacename]#EntityManager# to a JNDI address. By default, the JNDI providers
look for the [interfacename]#EntityManager# from "
java:comp/env/persistence/em". This can be done with the following snippet in
[filename]#web.xml# or with similar configuration with annotations.


----
<persistence-context-ref>
<persistence-context-ref-name>
persistence/em
</persistence-context-ref-name>
<persistence-unit-name>MYPU</persistence-unit-name>
</persistence-context-ref>
----

The " [literal]#++MYPU++#" is the identifier of your persistence unit defined in
your [filename]#persistence.xml# file.

If you choose to annotate your servlets (instead of using the
[filename]#web.xml# file as described above), you can simply add the following
annotation to your servlet.


----
@PersistenceContext(name="persistence/em",unitName="MYPU")
----

If you wish to use another address for the persistence context, you can define
them with the [methodname]#setJndiAddresses()# method. You can also define the
location for the JTA [classname]#UserTransaction#, but that should be always
accessible from " java:comp/UserTransaction" by the JEE6 specification.


[[jpacontainer.entityprovider.ejb]]
== Entity Providers as Enterprise Beans

Entity providers can be Enterprise JavaBeans (EJB). This may be useful if you
use JPAContainer in a Java EE application server. In such case, you need to
implement a custom entity provider that allows the server to inject the entity
manager.

For example, if you need to use Java Transaction API (JTA) for JPA transactions,
you can implement such entity provider as follows. Just extend a built-in entity
provider of your choise and annotate the entity manager member as
[literal]#++@PersistenceContext++#. Entity providers can be either stateless or
stateful session beans. If you extend a caching entity provider, it has to be
stateful.


----
@Stateless
@TransactionManagement
public class MyEntityProviderBean extends
MutableLocalEntityProvider<MyEntity> {

@PersistenceContext
private EntityManager em;

protected LocalEntityProviderBean() {
super(MyEntity.class);
setTransactionsHandledByProvider(false);
}

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
protected void runInTransaction(Runnable operation) {
super.runInTransaction(operation);
}

@PostConstruct
public void init() {
setEntityManager(em);
/*
* The entity manager is transaction-scoped, which means
* that the entities will be automatically detached when
* the transaction is closed. Therefore, we do not need
* to explicitly detach them.
*/
setEntitiesDetached(false);
}
}
----

If you have more than one EJB provider, you might want to create an abstract
super class of the above and only define the entity type in implementations. You
can implement an entity provider as a managed bean in Spring Framefork the same
way.





+ 0
- 151
documentation/jpacontainer/jpacontainer-fieldfactory.asciidoc View File

@@ -1,151 +0,0 @@
---
title: Automatic Form Generation
order: 8
layout: page
---

[[jpacontainer.fieldfactory]]
= Automatic Form Generation

The JPAContainer [classname]#FieldFactory# is an implementation of the
[interfacename]#FormFieldFactory# and [interfacename]#TableFieldFactory#
interfaces that can generate fields based on JPA annotations in a POJO. It goes
further than the [classname]#DefaultFieldFactory#, which only creates simple
fields for the basic data types. This way, you can easily create forms to input
entities or enable editing in tables.

The generated defaults are as follows:

[options="header"]
|===============
|Annotation|Class Mapping
|[literal]#++@ManyToOne++#|[classname]#NativeSelect#
|[literal]#++@OneToOne++#, [literal]#++@Embedded++#|Nested [classname]#Form#
|[literal]#++@OneToMany++#, [literal]#++@ElementCollection++#|[classname]#MasterDetailEditor# (see below)
|[literal]#++@ManyToMany++#|Selectable [classname]#Table#

|===============

The field factory is recursive, so that you can edit a complex object tree with one form.

[[jpacontainer.fieldfactory.configuring]]
== Configuring the Field Factory

The [classname]#FieldFactory# is highly configurable with various configuration settings and by extending.
// You need to make the configuration before ...

The [methodname]#setMultiSelectType()# and [methodname]#setSingleSelectType()#
allow you to specify a selection component that is used instead of the default
for a field with [literal]#++@ManyToMany++# and [literal]#++@ManyToOne++#
annotation, respectively. The first parameter is the class type of the field,
and the second parameter is the class type of a selection component. It must be
a sub-class of [classname]#AbstractSelect#.

The [methodname]#setVisibleProperties()# controls which properties (fields) are
visible in generated forms, subforms, and tables. The first paramater is the
class type for which the setting should be made, followed by the IDs of the
visible properties.

The configuration should be done before binding the form to a data source as
that is when the field generation is done.

Further configuration must be done by extending the many protected methods.
Please see the API documentation for the complete list.


[[jpacontainer.fieldfactory.using]]
== Using the Field Factory

The most basic use case for the JPAContainer [classname]#FieldFactory# is with a
[classname]#Form# bound to a container item:


----
// Have a persistent container
final JPAContainer<Country> countries =
JPAContainerFactory.make(Country.class, "book-examples");

// For selecting an item to edit
final ComboBox countrySelect =
new ComboBox("Select a Country", countries);
countrySelect.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY);
countrySelect.setItemCaptionPropertyId("name");

// Country Editor
final Form countryForm = new Form();
countryForm.setCaption("Country Editor");
countryForm.addStyleName("bordered"); // Custom style
countryForm.setWidth("420px");
countryForm.setBuffered(true);
countryForm.setEnabled(false);

// When an item is selected from the list...
countrySelect.addValueChangeListener(new ValueChangeListener(){
@Override
public void valueChange(ValueChangeEvent event) {
// Get the item to edit in the form
Item countryItem =
countries.getItem(event.getProperty().getValue());

// Use a JPAContainer field factory
// - no configuration is needed here
final FieldFactory fieldFactory = new FieldFactory();
countryForm.setFormFieldFactory(fieldFactory);

// Edit the item in the form
countryForm.setItemDataSource(countryItem);
countryForm.setEnabled(true);

// Handle saves on the form
final Button save = new Button("Save");
countryForm.getFooter().removeAllComponents();
countryForm.getFooter().addComponent(save);
save.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
countryForm.commit();
countryForm.setEnabled(false);
} catch (InvalidValueException e) {
}
}
});
}
});
countrySelect.setImmediate(true);
countrySelect.setNullSelectionAllowed(false);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.fieldfactory.formonetoone[on-line example, window="_blank"].

This would create a form shown in <<figure.jpacontainer.fieldfactory.using>>.

[[figure.jpacontainer.fieldfactory.using]]
.Using FieldFactory with One-to-Many Relationship
image::img/fieldfactory-form.png[]

If you use Hibernate, you also need to pass an
[classname]#EntityManagerPerRequestHelper#, either for the constructor or with
[methodname]#setEntityManagerPerRequestHelper()#
ifdef::web[]
, as described in
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.em-per-request,"The
EntityManager-Per-Request
pattern">>
endif::web[]
.


[[jpacontainer.fieldfactory.masterdetaileditor]]
== Master-Detail Editor

The [classname]#MasterDetailEditor# is a field component that allows editing an
item property that has one-to-many relationship. The item can be a row in a
table or bound to a form. It displays the referenced collection as an editable
[classname]#Table# and allows adding and removing items in it.

You can use the [classname]#MasterDetailEditor# manually, or perhaps more
commonly use a JPAContainer [classname]#FieldFactory# to create it
automatically. As shown in the example in
<<figure.jpacontainer.fieldfactory.using>>, the factory creates a
[classname]#MasterDetailEditor# for all properties with a
[literal]#++@OneToMany++# or an [literal]#++@ElementCollection++# annotation.

+ 0
- 95
documentation/jpacontainer/jpacontainer-filtering-criteria-api.asciidoc View File

@@ -1,95 +0,0 @@
---
title: Querying with the Criteria API
order: 7
layout: page
---

[[jpacontainer.filtering.criteria-api]]
= Querying with the Criteria API

When the [interfacename]#Filterable# API is not enough and you need to have more
control, you can make queries directly with the JPA Criteria API. You may also
need to customize sorting or joins, or otherwise modify the query in some way.
To do so, you need to implement a [interfacename]#QueryModifierDelegate# that
the JPAContainer entity provider calls when making a query. The easiest way to
do this is to extend [classname]#DefaultQueryModifierDelegate#, which has empty
implementations of all the methods so that you can only override the ones you
need.

The entity provider calls specific [interfacename]#QueryModifierDelegate#
methods at different stages while making a query. The stages are:

. Start building a query

. Add " [literal]#++ORDER BY++#" expression

. Add " [literal]#++WHERE++#" expression (filter)

. Finish building a query


Methods where you can modify the query are called before and after each stage as
listed in the following table:

[[table.jpacontainer.filtering.criteria-api.methods]]
.[classname]#QueryModifierDelegate# Methods

|===============
|[methodname]#queryWillBeBuilt()#
|[methodname]#orderByWillBeAdded()#
|[methodname]#orderByWasAdded()#
|[methodname]#filtersWillBeAdded()#
|[methodname]#filtersWereAdded()#
|[methodname]#queryHasBeenBuilt()#

|===============



All the methods get two parameters. The [interfacename]#CriteriaBuilder# is a
builder that you can use to build queries. The [interfacename]#CriteriaQuery# is
the query being built.

You can use the [methodname]#getRoots().iterator().next()# in
[interfacename]#CriteriaQuery# to get the "root" that is queried, for example,
the [literal]#++PERSON++# table, etc.

[[jpacontainer.filtering.criteria-api.filters]]
== Filtering the Query

Let us consider a case where we modify the query for a [classname]#Person#
container so that it includes only people over 116. This trivial example is
identical to the one given earlier using the [classname]#Filterable# interface.


----

persons.getEntityProvider().setQueryModifierDelegate(
new DefaultQueryModifierDelegate () {
@Override
public void filtersWillBeAdded(
CriteriaBuilder criteriaBuilder,
CriteriaQuery<?> query,
List<Predicate> predicates) {
Root<?> fromPerson = query.getRoots().iterator().next();

// Add a "WHERE age > 116" expression
Path<Integer> age = fromPerson.<Integer>get("age");
predicates.add(criteriaBuilder.gt(age, 116));
}
});
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.criteria.querymodification[on-line example, window="_blank"].


[[jpacontainer.filtering.criteria-api.compatibility]]
== Compatibility

When building queries, you should consider the capabilities of the different JPA
implementations. Regarding Hibernate, see
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.joins,"Joins
in Hibernate vs EclipseLink">>.





+ 0
- 45
documentation/jpacontainer/jpacontainer-filtering.asciidoc View File

@@ -1,45 +0,0 @@
---
title: Filtering JPAContainer
order: 6
layout: page
---

[[jpacontainer.filtering]]
= Filtering [classname]#JPAContainer#

Normally, a [classname]#JPAContainer# contains all instances of a particular
entity type in the persistence context. Hence, it is equivalent to a database
table or query. Just like with database queries, you often want to narrow the
results down. [classname]#JPAContainer# implements the
[interfacename]#Filterable# interface in Vaadin containers, described in
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.filtered,"Filterable
Containers">>. All filtering is done at the database level with queries, not in
the container.

For example, let us filter all the people older than 117:


----
Filter filter = new Compare.Greater("age", 117);
persons.addContainerFilter(filter);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.filtering.basic[on-line example, window="_blank"].

This would create a JPQL query somewhat as follows:


----
SELECT id FROM Person WHERE (AGE > 117)
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.filtering.basic[on-line example, window="_blank"].

The filtering implementation uses the JPA 2.0 Criteria API transparently. As the
filtering is done at the database-level, custom filters that use the
[interfacename]#Filterable# API do not work.

When using Hibernate, note that it does not support implicit joins. See
<<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.joins,"Joins
in Hibernate vs EclipseLink">> for more details.




+ 0
- 180
documentation/jpacontainer/jpacontainer-hibernate.asciidoc View File

@@ -1,180 +0,0 @@
---
title: Using JPAContainer with Hibernate
order: 9
layout: page
---

[[jpacontainer.hibernate]]
= Using JPAContainer with Hibernate

Hibernate needs special handling in some cases.

[[jpacontainer.hibernate.lazyloading]]
== Lazy loading

In order for lazy loading to work automatically, an entity must be attached to
an entity manager. Unfortunately, Hibernate can not keep entity managers for
long without problems. To work around the problem, you need to use a special
lazy loading delegate for Hibernate.

JPAContainer entity providers handle lazy loading in delegates defined by the
[interfacename]#LazyLoadingDelegate# interface. The default implementation for
Hibernate is defined in [classname]#HibernateLazyLoadingDelegate#. You can
instantiate one and use it in an entity provider with
[methodname]#setLazyLoadingDelegate()#.

The default implementation works so that whenever a lazy property is accessed
through the Vaadin Property interface, the value is retrieved with a separate
(JPA Criteria API) query using the currently active entity manager. The value is
then manually attached to the entity instance, which is detached from the entity
manager. If this default implementation is not good enough, you may need to make
your own implementation.


ifdef::web[]
[[jpacontainer.hibernate.em-per-request]]
== The EntityManager-Per-Request pattern

One issue with Hibernate is that it is designed for short-lived sessions, but
the lifetime of an entity manager is normally roughly that of a user session.
The problem is that if an error occurs in a session or an entity manager, the
manager becomes unuseable. This causes big problems with long-lived sessions
that would work fine with EclipseLink.

The recommended solution is to use the __EntityManager-per-Request__ pattern. It
is highly recommended always when using Hibernate.

An entity manager can only be open during the request-response cycle of the
Vaadin servlet, so that one is created at the beginning of the request and
closed at the end.

[[jpacontainer.hibernate.em-per-request.provider]]
=== Storing an Entity Manager

You first need to implement an [interfacename]#EntityManagerProvider# that
returns a stored [interfacename]#EntityManager# with
[methodname]#getEntityManager()#. The entity manager must be stored in a
[classname]#ThreadLocal# variable.


----
public class LazyHibernateEntityManagerProvider
implements EntityManagerProvider {
private static ThreadLocal<EntityManager>
entityManagerThreadLocal =
new ThreadLocal<EntityManager>();

@Override
public EntityManager getEntityManager() {
return entityManagerThreadLocal.get();
}

public static void setCurrentEntityManager(
EntityManager em) {
entityManagerThreadLocal.set(em);
}
}
----

You need to create and store the per-request instance at the beginning of each
request with [methodname]#setCurrentEntityManager()# and clear it at the end by
setting it as [literal]#++null++#.


[[jpacontainer.hibernate.em-per-request.provider]]
=== Creating Entity Managers in a Servlet Filter

You can create the entity managers for each request either by extending
[classname]#VaadinServlet# and overriding the [methodname]#service()# method or
by implementing a servlet filter. In the following, we describe how to implement
a servlet filter to do the task, but overriding the servlet could be even
easier.


----
public class LazyHibernateServletFilter
implements Filter {

private EntityManagerFactory entityManagerFactory;

@Override
public void init(FilterConfig filterConfig)
throws ServletException {
entityManagerFactory = Persistence
.createEntityManagerFactory("lazyhibernate");
}

@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
try {
// Create and set the entity manager
LazyHibernateEntityManagerProvider
.setCurrentEntityManager(
entityManagerFactory
.createEntityManager());

// Handle the request
filterChain.doFilter(servletRequest,
servletResponse);
} finally {
// Reset the entity manager
LazyHibernateEntityManagerProvider
.setCurrentEntityManager(null);
}
}

@Override
public void destroy() {
entityManagerFactory = null;
}
}
----

You need to define the servlet filter in the [filename]#web.xml# deployment
descriptor as follows:

[subs="normal"]
----
&lt;filter&gt;
&lt;filter-name&gt;**LazyHibernateServletFilter**&lt;/filter-name&gt;
&lt;filter-class&gt;**com.example.LazyHibernateServletFilter**&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;**LazyHibernateServletFilter**&lt;/filter-name&gt;
&lt;url-pattern&gt;**/++*++**&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
----
The [literal]#++url-pattern++# must match the pattern for your Vaadin servlet.


endif::web[]

[[jpacontainer.hibernate.joins]]
== Joins in Hibernate vs EclipseLink

EclipseLink supports implicit joins, while Hibernate requires explicit joins. In
SQL terms, an explicit join is a " [literal]#++FROM a INNER JOIN b ON a.bid =
b.id++#" expression, while an implicit join is done in a WHERE clause, such as:
" [literal]#++FROM a,b WHERE a.bid = b.id++#".

In a JPAContainer filter with EclipseLink, an implicit join would have form:


----
new Equal("skills.skill", s)
----

In Hibernate you would need to use [classname]#JoinFilter# for the explicit
join:


----
new JoinFilter("skills", new Equal("skill", s))
----





+ 0
- 305
documentation/jpacontainer/jpacontainer-installation.asciidoc View File

@@ -1,305 +0,0 @@
---
title: Installing
order: 2
layout: page
---

[[jpacontainer.installation]]
= Installing

Vaadin JPAContainer can be installed either as an installation package,
downloaded from the Vaadin Directory, or as a Maven dependency. You can also
create a new JPAContainer-enabled Vaadin project using a Maven archetype.

[[jpacontainer.installation.download]]
== Downloading the Package

Vaadin JPAContainer is available for download from the
link:http://vaadin.com/directory[Vaadin Directory]. Please see
<<dummy/../../../framework/addons/addons-downloading#addons.downloading,"Downloading
Add-ons from Vaadin Directory">> for basic instructions for downloading from
Directory. The download page also gives the dependency declaration needed for
retrieving the library with Maven.

JPAContainer is a purely server-side component, so it does not include a widget
set that you would need to compile.


[[jpacontainer.installation.package]]
== Installation Package Content

Once extracted to a local folder, the contents of the installation directory are
as follows:

[filename]#README#:: A readme file describing the package contents.

[filename]#LICENSE#:: The full license text for the library.

[filename]#vaadin-jpacontainer-3.x.x.jar#:: The actual Vaadin JPAContainer library.

[filename]#vaadin-jpacontainer-3.x.x-sources.jar#:: Source JAR for the library. You can use it for example in Eclipse by associating
the JavaDoc JAR with the JPAContainer JAR in the build path settings of your
project.

[filename]#jpacontainer-tutorial.pdf#:: The tutorial in PDF format.

[filename]#jpacontainer-tutorial-html#:: The tutorial in HTML format.

[filename]#jpacontainer-addressbook-demo#:: The JPAContainer AddressBook Demo project covered in this tutorial. You can
compile and package the application as a WAR with " [command]#mvn#
[parameter]#package#" or launch it in the Jetty web browser with "
[command]#mvn# [parameter]#jetty:run#". You can also import the demo project in
Eclipse.




[[jpacontainer.installation.maven]]
== Downloading with Maven

The link:http://vaadin.com/directory[download page in Vaadin Directory] gives
the dependency declaration needed for retrieving the Vaadin JPAContainer library
with Maven.

[subs="normal"]
----
<dependency>
<groupId>com.vaadin.addon</groupId>
<artifactId>jpacontainer</artifactId>
<version>[replaceable]##3.2.0##</version>
</dependency>
----

Use the [literal]#++LATEST++# version tag to automatically download the latest
stable release or use a specific version number as done above.

See <<dummy/../../../framework/addons/addons-maven#addons.maven,"Using Add-ons
in a Maven Project">> for detailed instructions for using a Vaadin add-on with
Maven.

[[jpacontainer.installation.maven.archetype]]
=== Using the Maven Archetype

If you wish to create a new JPAContainer-enabled Vaadin project with Maven, you
can use the [literal]#++vaadin-archetype-jpacontainer++# archetype. Please see
<<dummy/../../../framework/getting-started/getting-started-maven#getting-started.maven,"Using
Vaadin with Maven">> for details on creating a Vaadin project with a Maven
archetype.



[[jpacontainer.installation.libraries]]
== Including Libraries in Your Project

The Vaadin JPAContainer JAR must be included in the library folder of the web
application. It is located in [filename]#WEB-INF/lib# path in a web application.
In a normal Eclipse web projects the path is [filename]#WebContent/WEB-INF/lib#.
In Maven projects the JARs are automatically included in the folder, as long as
the dependencies are defined correctly.

You will need the following JARs:

* Vaadin Framework Library

* Vaadin JPAContainer

* Java Persistence API 2.0 (javax.persistence package)

* JPA implementation (EclipseLink, Hibernate, ...)

* Database driver or embedded engine (H2, HSQLDB, MySQL, PostgreSQL, ...)


If you use Eclipse, the Vaadin Framework library is automatically downloaded and
updated by the Vaadin Plugin for Eclipse.

To use bean validation, you need an implementation of the Bean Validation, such
as Hibernate Validator.//TODO
elaborate


[[jpacontainer.installation.configuration]]
== Persistence Configuration

Persistence configuration is done in a [filename]#persistence.xml# file. In a
regular Eclipse project, it should be located in
[filename]#WebContent/WEB-INF/classes/META-INF#. In a Maven project, it should
be in [filename]#src/main/resources/META-INF#. The configuration includes the
following:

* The persistence unit

* The persistence provider

* The database driver and connection

* Logging


The [filename]#persistence.xml# file is packaged as
[filename]#WEB-INF/classes/META-INF/persistence.xml# in the WAR. This is done
automatically in a Maven build at the package phase.

[[jpacontainer.installation.configuration.schema]]
=== Persistence XML Schema

The beginning of a [filename]#persistence.xml# file defines the used schema and
namespaces:


----
<?xml version="1.0" encoding="UTF-8"?>
<persistence
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"
version="2.0">
----


[[jpacontainer.installation.configuration.unit]]
=== Defining the Persistence Unit

The root element of the persistence definition is persistence-unit. The name of
the persistence unit is needed for creating [classname]#JPAContainer# instances
from a [classname]#JPAContainerFactory#, as described in
<<dummy/../../../framework/jpacontainer/jpacontainer-usage#jpacontainer.usage.jpacontainerfactory,"Creating
JPAContainer with JPAContainerFactory">> or when creating a JPA entity manager.


----
<persistence-unit name="addressbook">
----

Persistence provider is the JPA provider implementation used. For example, the
JPAContainer AddressBook demo uses the EclipseLink JPA, which is defined as
follows:


----
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>
----

The persistent classes need to be listed with a [literal]#++<class>++# element.
Alternatively, you can allow including unlisted classes for persistence by
overriding the [literal]#++exclude-unlisted-classes++# default as follows:


----
<exclude-unlisted-classes>false</exclude-unlisted-classes>
----

JPA provider specific parameters are given under the [literal]#++properties++#
element.


----
<properties>
...
----

In the following section we give parameters for the EclipseLink JPA and H2
database used in the JPAContainer AddressBook Demo. Please refer to the
documentation of the JPA provider you use for a complete reference of
parameters.


[[jpacontainer.installation.configuration.database]]
=== Database Connection

EclipseLink allows using JDBC for database connection. For example, if we use
the the H2 database, we define its driver here as follows:


----
<property name="eclipselink.jdbc.platform"
value="org.eclipse.persistence.platform.database.H2Platform"/>
<property name="eclipselink.jdbc.driver"
value="org.h2.Driver" />
----

Database connection is specified with a URL. For example, using an embedded H2
database stored in the home directory it would be as follows:


----
<property name="eclipselink.jdbc.url"
value="jdbc:h2:~/my-app-h2db"/>
----

A hint: when using an embedded H2 database while developing a Vaadin application
in Eclipse, you may want to add [literal]#++;FILE_LOCK=NO++# to the URL to avoid
locking issues when redeploying.

We can just use the default user name and password for the H2 database:


----
<property name="eclipselink.jdbc.user" value="sa"/>
<property name="eclipselink.jdbc.password" value="sa"/>
----


[[jpacontainer.installation.configuration.logging]]
=== Logging Configuration

JPA implementations as well as database engines like to produce logs and they
should be configured in the persistence configuration. For example, if using
EclipseLink JPA, you can get log that includes all SQL statements with the
[literal]#++FINE++# logging level:


----
<property name="eclipselink.logging.level"
value="FINE" />
----


[[jpacontainer.installation.configuration.other]]
=== Other Settings

The rest is some Data Definition Language settings for EclipseLink. During
development, when we use generated example data, we want EclipseLink to drop
tables before trying to create them. In production environments, you should use
[literal]#++create-tables++#.


----
<property name="eclipselink.ddl-generation"
value="drop-and-create-tables" />
----

And there is no need to generate SQL files, just execute them directly to the
database.


----
<property name="eclipselink.ddl-generation.output-mode"
value="database"/>
</properties>
</persistence-unit>
</persistence>
----



[[jpacontainer.installation.troubleshooting]]
== Troubleshooting

Below are some typical errors that you might get when using JPA. These are not
specific to JPAContainer.

[classname]#javax.persistence.PersistenceException#: No Persistence provider for EntityManager:: The most typical cases for this error are that the persistence unit name is
wrong in the source code or in the [filename]#persistence.xml# file, or that the
[filename]#persistence.xml# is at a wrong place or has some other problem. Make
sure that the persistence unit name matches and the [filename]#persistence.xml#
is in [filename]#WEB-INF/classes/META-INF# folder in the deployment.

[classname]#java.lang.IllegalArgumentException#: The class is not an entity:: The class is missing from the set of persistent entities. If the
[filename]#persistence.xml# does not have [parameter]#exclude-unlisted-classes#
defined as [literal]#++false++#, the persistent entity classes should be listed
with [literal]#++<class>++# elements.

+ 0
- 124
documentation/jpacontainer/jpacontainer-overview.asciidoc View File

@@ -1,124 +0,0 @@
---
title: Overview
order: 1
layout: page
---

[[jpacontainer.overview]]
= 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 [classname]#BeanItemContainer#. You should also note the https://vaadin.com/directory#!addon/viritin[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 [interfacename]#Container# interface described in
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container,"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.

[[figure.jpacontainer.overview.architecture]]
.Three-Layer Architecture Using JPAContainer And JPA
image::img/three-layer-architecture-hi.png[]

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 <<figure.jpacontainer.overview.detailed-architecture>>.

[[figure.jpacontainer.overview.detailed-architecture]]
.JPAContainer Architecture
image::img/detailed-architecture-hi.png[]

Vaadin JPAContainer also plays together with the Vaadin support for Java Bean
Validation (JSR 303).

[[jpacontainer.overview.jpa]]
== 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
<<figure.jpacontainer.overview.jpa.orm>> with two entities with a one-to-many
relationship.

[[figure.jpacontainer.overview.jpa.orm]]
.Object-Relational Mapping
image::img/jpa-mapping-graphic-hi.png[]

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
<<dummy/../../../framework/jpacontainer/jpacontainer-domain-model#jpacontainer.domain-model.annotation,"Persistence
Metadata">>.

The main interface in JPA is the [interfacename]#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.overview.concepts]]
== JPAContainer Concepts

The [classname]#JPAContainer# is an implementation of the Vaadin
[interfacename]#Container# interface that you can bind to user interface
components such as [classname]#Table#, [classname]#ComboBox#, etc.

The data access to the persistent entities is handled with a __entity
provider__, as defined in the [interfacename]#EntityProvider# interface.
JPAContainer provides a number of different entity providers for different use
cases and optimizations. The built-in providers are described in
<<dummy/../../../framework/jpacontainer/jpacontainer-entityprovider#jpacontainer.entityprovider,"Entity
Providers">>.

[classname]#JPAContainer# is by default __unbuffered__, so that any entity
property changes are written immediately to the database when you call
[methodname]#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
[methodname]#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
[classname]#OptimisticLockException# when two users edit the same item (an
unbuffered container never throws it), thereby allowing to handle the situation
with application logic.


[[jpacontainer.overview.documentation]]
== Documentation and Support

In addition to this chapter in the book, the installation package includes the
following documentation about JPAContainer:

* API Documentation

* JPAContainer Tutorial

* JPAContainer AddressBook Demo

* JPAContainer Demo

+ 0
- 386
documentation/jpacontainer/jpacontainer-usage.asciidoc View File

@@ -1,386 +0,0 @@
---
title: Basic Use of JPAContainer
order: 4
layout: page
---

[[jpacontainer.usage]]
= Basic Use of JPAContainer

Vaadin JPAContainer offers a highly flexible API that makes things easy in
simple cases while allowing extensive flexibility in demanding cases. To begin
with, it is a [classname]#Container#, as described in
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container,"Collecting
Items in Containers">>.

In this section, we look how to create and use [classname]#JPAContainer#
instances. We assume that you have defined a domain model with JPA annotations,
as described in the previous section.

[[jpacontainer.usage.jpacontainerfactory]]
== Creating [classname]#JPAContainer# with [classname]#JPAContainerFactory#

The [classname]#JPAContainerFactory# is the easy way to create
[classname]#JPAContainer#s. It provides a set of __make...()__ factory methods
for most cases that you will likely meet. Each factory method uses a different
type of entity provider, which are described in
<<dummy/../../../framework/jpacontainer/jpacontainer-entityprovider#jpacontainer.entityprovider,"Entity
Providers">>.

The factory methods take the class type of the entity class as the first
parameter. The second parameter is either a persistence unit name (persistence
context) or an [classname]#EntityManager# instance.


----
// Create a persistent person container
JPAContainer<Person> persons =
JPAContainerFactory.make(Person.class, "book-examples");

// You can add entities to the container as well
persons.addEntity(new Person("Marie-Louise Meilleur", 117));

// Set up sorting if the natural order is not appropriate
persons.sort(new String[]{"age", "name"},
new boolean[]{false, false});

// Bind it to a component
Table personTable = new Table("The Persistent People", persons);
personTable.setVisibleColumns("id","name","age");
layout.addComponent(personTable);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.basic[on-line example, window="_blank"].

It's that easy. In fact, if you run the above code multiple times, you'll be
annoyed by getting a new set of persons for each run - that's how persistent the
container is. The basic [methodname]#make()# uses a
[classname]#CachedMutableLocalEntityProvider#, which allows modifying the
container and its entities, as we do above by adding new entities.

When using just the persistence unit name, the factory creates an instance of
[classname]#EntityManagerFactory# for the persistence unit and uses it to build
entity managers. You can also create the entity managers yourself, as described
later.

The entity providers associated with the different factory methods are as
follows:

[[table.jpacontainer.usage.jpacontainerfactory]]
.[classname]#JPAContainerFactory# Methods

|===============
|[methodname]#make()#|[classname]#CachingMutableLocalEntityProvider#
|[methodname]#makeReadOnly()#|[classname]#CachingLocalEntityProvider#
|[methodname]#makeBatchable()#|[classname]#BatchableLocalEntityProvider#
|[methodname]#makeNonCached()#|[classname]#MutableLocalEntityProvider#
|[methodname]#makeNonCachedReadOnly()#|[classname]#LocalEntityProvider#

|===============



[classname]#JPAContainerFactory# holds a cache of entity manager factories for
the different persistence units, making sure that any entity manager factory is
created only once, as it is a heavy operation. You can access the cache to get a
new entity manager with the
[methodname]#createEntityManagerForPersistenceUnit()# method.


----
// Get an entity manager
EntityManager em = JPAContainerFactory.
createEntityManagerForPersistenceUnit("book-examples");

// Do a query
em.getTransaction().begin();
em.createQuery("DELETE FROM Person p").executeUpdate();
em.persist(new Person("Jeanne Calment", 122));
em.persist(new Person("Sarah Knauss", 119));
em.persist(new Person("Lucy Hannah", 117));
em.getTransaction().commit();

...
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.basic[on-line example, window="_blank"].

Notice that if you use update the persistent data with an entity manager outside
a [classname]#JPAContainer# bound to the data, you need to refresh the container
as described in <<jpacontainer.usage.entitites>>.

[[jpacontainer.usage.jpacontainerfactory.thehardway]]
=== Creating [classname]#JPAContainer# Manually

While it is normally easiest to use a [classname]#JPAContainerFactory# to create
[classname]#JPAContainer# instances, you may need to create them manually. It is
necessary, for example, when you need to use a custom entity provider or extend
[classname]#JPAContainer#.

First, we need to create an entity manager and then the entity provider, which
we bind to a [classname]#JPAContainer#.


----
// We need a factory to create entity manager
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("book-examples");

// We need an entity manager to create entity provider
EntityManager em = emf.createEntityManager();

// We need an entity provider to create a container
CachingMutableLocalEntityProvider<Person> entityProvider =
new CachingMutableLocalEntityProvider<Person>(Person.class,
em);

// And there we have it
JPAContainer<Person> persons =
new JPAContainer<Person> (Person.class);
persons.setEntityProvider(entityProvider);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.thehardway[on-line example, window="_blank"].

You could save the first step by asking the entity manager from the
[classname]#JPAContainerFactory#.



[[jpacontainer.usage.entitites]]
== Creating and Accessing Entities

JPAContainer integrates with the JPA entity manager, which you would normally
use to create and access entities with JPA. You can use the entity manager for
any purposes you may have, and then [classname]#JPAContainer# to bind entities
to user interface components such as [classname]#Table#, [classname]#Tree#, any
selection components, or a [classname]#Form#.

You can add new entities to a [classname]#JPAContainer# with the
[methodname]#addEntity()# method. It returns the item ID of the new entity.


----
Country france = new Country("France");
Object itemId = countries.addEntity(france);
----

The item ID used by [classname]#JPAContainer# is the value of the ID property
(column) defined with the [literal]#++@Id++# annotation. In our
[classname]#Country# entity, it would have [classname]#Long# type. It is
generated by the entity manager when the entity is persisted and set with the
setter for the ID proeprty.

Notice that the [methodname]#addEntity()# method does __not__ attach the entity
instance given as the parameter. Instead, it creates a new instance. If you need
to use the entity for some purpose, you need to get the actual managed entity
from the container. You can get it with the item ID returned by
[methodname]#addEntity()#.


----
// Create a new entity and add it to a container
Country france = new Country("France");
Object itemId = countries.addEntity(france);

// Get the managed entity
france = countries.getItem(itemId).getEntity();

// Use the managed entity in entity references
persons.addEntity(new Person("Jeanne Calment", 122, france));
----

[[jpacontainer.usage.entitites.items]]
=== Entity Items

The [methodname]#getItem()# method is defined in the normal Vaadin
[interfacename]#Container# interface. It returns an [classname]#EntityItem#,
which is a wrapper over the actual entity object. You can get the entity object
with [methodname]#getEntity()#.

An [classname]#EntityItem# can have a number of states: persistent, modified,
dirty, and deleted. The dirty and deleted states are meaningful when using
__container buffering__, while the modified state is meaningful when using
__item buffering__. Both levels of buffering can be used together - user input
is first written to the item buffer, then to the entity instance, and finally to
the database.

The [methodname]#isPersistent()# method tells if the item is actually
persistent, that is, fetched from a persistent storage, or if it is just a
transient entity created and buffered by the container.

The [methodname]#isModified()# method checks whether the [classname]#EntityItem#
has changes that are not yet committed to the entity instance. It is only
relevant if the item buffering is enabled with [methodname]#setBuffered(true)#
for the item.

The [methodname]#isDirty()# method checks whether the entity object has been
modified after it was fetched from the entity provider. The dirty state is
possible only when buffering is enabled for the container.

The [methodname]#isDeleted()# method checks whether the item has been marked for
deletion with [methodname]#removeItem()# in a buffered container.


[[jpacontainer.usage.entitites.refreshing]]
=== Refreshing JPAContainer

In cases where you change [classname]#JPAContainer# items outside the container,
for example by through an [interfacename]#EntityManager#, or when they change in
the database, you need to refresh the container.

The [interfacename]#EntityContainer# interface implemented by
[classname]#JPAContainer# provides two methods to refresh a container. The
[methodname]#refresh()# discards all container caches and buffers and refreshes
all loaded items in the container. All changes made to items provided by the
container are discarded. The [methodname]#refreshItem()# refreshes a single
item.



[[jpacontainer.usage.nested-properties]]
== Nested Properties

If you have a one-to-one or many-to-one relationship, you can define the
properties of the referenced entity as __nested__ in a
[classname]#JPAContainer#. This way, you can access the properties directly
through the container of the first entity type as if they were its properties.
The interface is the same as with [classname]#BeanContainer# described in
<<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.beancontainer,"BeanContainer">>.
You just need to add each nested property with
[methodname]#addNestedContainerProperty()# using dot-separated path to the
property.


----
// Have a persistent container
JPAContainer<Person> persons =
JPAContainerFactory.make(Person.class, "book-examples");

// Add a nested property to a many-to-one property
persons.addNestedContainerProperty("country.name");
// Show the persons in a table, except the "country" column,
// which is an object - show the nested property instead
Table personTable = new Table("The Persistent People", persons);
personTable.setVisibleColumns("name", "age", "country.name");

// Have a nicer caption for the country.name column
personTable.setColumnHeader("country.name", "Nationality");
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.nested[on-line example, window="_blank"].

The result is shown in <<figure.jpacontainer.usage.nested-properties>>. Notice
that the [literal]#++country++# property in the container remains after adding
the nested property, so we had to make that column invisible. Alternatively, we
could have redefined the [methodname]#toString()# method in the country object
to show the name instead of an object reference.

[[figure.jpacontainer.usage.nested-properties]]
.Nested Properties
image::img/nested-properties.png[]

You can use the [literal]#++*++# wildcard to add all properties in a nested
item, for example, " [literal]#++country.*++#".


[[jpacontainer.usage.hierarchical]]
== Hierarchical Container

[classname]#JPAContainer# implements the [interfacename]#Container.Hierarchical#
interface and can be bound to hierarchical components such as a
[classname]#Tree# or [classname]#TreeTable#. The feature requires that the
hierarchy is represented with a __parent__ property that refers to the parent
item. At database level, this would be a column with IDs.

The representation would be as follows:


----
@Entity
public class CelestialBody implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;

@ManyToOne
private CelestialBody parent;
...
} ...

// Create some entities
CelestialBody sun = new CelestialBody("The Sun", null);
CelestialBody mercury = new CelestialBody("Mercury", sun);
CelestialBody venus = new CelestialBody("Venus", sun);
CelestialBody earth = new CelestialBody("Earth", sun);
CelestialBody moon = new CelestialBody("The Moon", earth);
CelestialBody mars = new CelestialBody("Mars", sun);
...
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"].

You set up a [classname]#JPAContainer# to have hierarchy by calling
[methodname]#setParentProperty()# with the name of the property that refers to
the parent. Coincidentally, it is named " [literal]#++parent++#" in the example:


----
// Create the container
JPAContainer<CelestialBody> bodies =
JPAContainerFactory.make(CelestialBody.class, "my-unit");

// Set it up for hierarchical representation
bodies.setParentProperty("parent");

// Bind it to a hierarhical component
Tree tree = new Tree("Celestial Bodies", bodies);
tree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_PROPERTY);
tree.setItemCaptionPropertyId("name");
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"].

You can use the [methodname]#rootItemIds()# to acquire the item IDs of the root
elements with no parent.


----
// Expand the tree
for (Object rootId: bodies.rootItemIds())
tree.expandItemsRecursively(rootId);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"].

[[jpacontainer.usage.hierarchical.unsupported]]
=== Unsupported Hierarchical Features

Using [methodname]#setParent()# in the container to define parenthood is not
supported.

Also, the current implementation does not support __setChildrenAllowed()__,
which controls whether the user can expand a node by clicking a toggle. The
toggle is by default visible for all nodes, even if they have no children. The
method is not supported because it would require storing the information outside
the entities. You can override [methodname]#areChildrenAllowed()# to implement
the functionality using a custom logic.


----
// Customize JPAContainer to define the logic for
// displaying the node expansion indicator
JPAContainer<CelestialBody> bodies =
new JPAContainer<CelestialBody>(CelestialBody.class) {
@Override
public boolean areChildrenAllowed(Object itemId) {
// Some simple logic
return getChildren(itemId).size() > 0;
}
};
bodies.setEntityProvider(
new CachingLocalEntityProvider<CelestialBody>(
CelestialBody.class, em));
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.hierarchical[on-line example, window="_blank"].






+ 0
- 1165
documentation/jpacontainer/original-drawings/detailed-architecture-web.svg
File diff suppressed because it is too large
View File


+ 0
- 1088
documentation/jpacontainer/original-drawings/detailed-architecture.svg
File diff suppressed because it is too large
View File


+ 0
- 938
documentation/jpacontainer/original-drawings/domain-model.svg View File

@@ -1,938 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448"
height="1052.3622"
id="svg2475"
sodipodi:version="0.32"
inkscape:version="0.48.2 r9819"
sodipodi:docname="domain-model.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/magi/itmill/doc/cheatsheet/vaadin-cheatsheet.png"
inkscape:export-xdpi="300.01001"
inkscape:export-ydpi="300.01001"
version="1.0">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.3941125"
inkscape:cx="447.08547"
inkscape:cy="609.40826"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1060"
inkscape:window-x="-4"
inkscape:window-y="-3"
inkscape:snap-nodes="true"
inkscape:snap-bbox="true"
units="mm"
inkscape:snap-global="true"
inkscape:window-maximized="1">
<inkscape:grid
spacingy="1mm"
spacingx="1mm"
empspacing="5"
units="mm"
enabled="true"
visible="true"
id="grid4674"
type="xygrid"
dotted="false" />
</sodipodi:namedview>
<defs
id="defs2477">
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path5210"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.8,0,0,0.8,10,0)" />
</marker>
<marker
style="overflow:visible"
id="DotS"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotS">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path3636" />
</marker>
<marker
inkscape:stockid="TriangleOutS"
orient="auto"
refY="0"
refX="0"
id="TriangleOutS"
style="overflow:visible">
<path
id="path3717"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<inkscape:path-effect
copytype="single_stretched"
pattern="M 349.202,225.086 L 405.895,331.386 L 370.462,338.472 "
prop_scale="1"
id="path-effect2503"
effect="skeletal" />
<inkscape:path-effect
prop_scale="1"
id="path-effect2499"
effect="skeletal" />
<inkscape:path-effect
pattern-nodetypes="cc"
pattern="M 432.28346,272.83462 L 403.93701,216.14171"
prop_scale="1"
id="path-effect2497"
effect="skeletal" />
<marker
style="overflow:visible"
id="Arrow1Send"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Send">
<path
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
id="path3641" />
</marker>
<marker
style="overflow:visible"
id="Arrow1Lend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
id="path3629" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3487" />
<marker
style="overflow:visible"
id="Arrow2Sendp"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Sendp">
<path
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
style="font-size:12px;fill:#f39300;fill-rule:evenodd;stroke:#f39300;stroke-width:0.625;stroke-linejoin:round"
id="path28139" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutSK"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutSK">
<path
transform="scale(0.2,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
id="path36611" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutSH"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutSH">
<path
transform="scale(0.2,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
id="path36614" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutSA"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutSA">
<path
transform="scale(0.2,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
id="path36617" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutSKF"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutSKF">
<path
transform="scale(0.2,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
id="path36620" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutS9"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutS9">
<path
transform="scale(0.2,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
id="path36623" />
</marker>
<marker
style="overflow:visible"
id="Arrow2SendpA"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2SendpA">
<path
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
style="font-size:12px;fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:0.625;stroke-linejoin:round"
id="path3396" />
</marker>
<marker
style="overflow:visible"
id="Arrow2Sendpg"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Sendpg">
<path
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
style="font-size:12px;fill:#fcc988;fill-rule:evenodd;stroke:#fcc988;stroke-width:0.625;stroke-linejoin:round"
id="path3360" />
</marker>
<filter
id="filter2780"
inkscape:label="White Halo"
width="1.1"
height="1.1">
<feMorphology
id="feMorphology2782"
operator="dilate"
radius="3"
result="result0" />
<feFlood
id="feFlood2786"
flood-color="rgb(255,255,255)"
flood-opacity="1"
in="result0"
result="result3" />
<feComposite
id="feComposite2623"
in="result3"
in2="result0"
operator="in"
result="result4" />
<feMerge
id="feMerge2629">
<feMergeNode
inkscape:collect="always"
id="feMergeNode2631"
in="result4" />
<feMergeNode
inkscape:collect="always"
id="feMergeNode2633"
in="SourceGraphic" />
</feMerge>
</filter>
<marker
inkscape:stockid="TriangleOutSn"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSn"
style="overflow:visible">
<path
id="path4441"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutS9F"
orient="auto"
refY="0"
refX="0"
id="TriangleOutS9F"
style="overflow:visible">
<path
id="path4444"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSI"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSI"
style="overflow:visible">
<path
id="path4447"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSO"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSO"
style="overflow:visible">
<path
id="path4450"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSW"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSW"
style="overflow:visible">
<path
id="path4453"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSB"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSB"
style="overflow:visible">
<path
id="path4456"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSZ"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSZ"
style="overflow:visible">
<path
id="path4459"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
style="overflow:visible"
id="DotSq"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSq">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill:#d9d9cd;fill-rule:evenodd;stroke:#d9d9cd;stroke-width:1pt;marker-start:none;marker-end:none"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path5853" />
</marker>
<marker
inkscape:stockid="TriangleOutSBO"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSBO"
style="overflow:visible">
<path
id="path7501"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
style="overflow:visible"
id="DotSu"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSu">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path9463" />
</marker>
<filter
height="1.1"
width="1.1"
inkscape:label="Black Halo"
id="filter10694">
<feMorphology
result="result0"
radius="3"
operator="dilate"
id="feMorphology10696" />
<feFlood
result="result3"
in="result0"
flood-opacity="1"
flood-color="rgb(0,0,0)"
id="feFlood10698" />
<feComposite
result="result4"
operator="in"
in2="result0"
in="result3"
id="feComposite10700" />
<feMerge
id="feMerge10702">
<feMergeNode
in="result4"
id="feMergeNode10704"
inkscape:collect="always" />
<feMergeNode
in="SourceGraphic"
id="feMergeNode10706"
inkscape:collect="always" />
</feMerge>
</filter>
<marker
inkscape:stockid="TriangleOutSu"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSu"
style="overflow:visible">
<path
id="path8127"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSI8"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSI8"
style="overflow:visible">
<path
id="path8130"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSr"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSr"
style="overflow:visible">
<path
id="path8133"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSM"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSM"
style="overflow:visible">
<path
id="path8136"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
inkscape:stockid="TriangleOutSb"
orient="auto"
refY="0"
refX="0"
id="TriangleOutSb"
style="overflow:visible">
<path
id="path8139"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none"
transform="scale(0.2,0.2)" />
</marker>
<marker
id="marker18095"
orient="auto"
markerHeight="5.7450776"
markerWidth="4.6297302">
<g
id="g11064"
transform="matrix(0.5,0,0,0.5,-185.64298,-257.19655)">
<path
sodipodi:nodetypes="csccccccsccssssssssssssssccc"
id="path11050"
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path11035"
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625"
style="fill:#49c2f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</marker>
<marker
id="marker44971"
orient="auto"
markerHeight="5.7450781"
markerWidth="4.6297355">
<g
id="g18059"
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)">
<path
sodipodi:nodetypes="csccccccsccssssssssssssssccc"
id="path18061"
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path18063"
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625"
style="fill:#d9d9cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</marker>
<marker
id="marker52016"
orient="auto"
markerHeight="5.7450786"
markerWidth="4.6297302">
<g
id="g52010"
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)">
<path
sodipodi:nodetypes="csccccccsccssssssssssssssccc"
id="path52012"
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path52014"
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625"
style="fill:#f39300;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</marker>
<marker
id="marker64887"
orient="auto"
markerHeight="5.745079"
markerWidth="4.6297255">
<g
id="g64855"
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)">
<path
sodipodi:nodetypes="csccccccsccssssssssssssssccc"
id="path64857"
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path64859"
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</marker>
<marker
id="marker4057"
orient="auto"
markerHeight="5.745079"
markerWidth="4.6297302">
<g
id="g51986"
transform="matrix(0.5,0,0,0.5,-185.64299,-257.19655)">
<path
sodipodi:nodetypes="csccccccsccssssssssssssssccc"
id="path51988"
d="M 370,508.65625 C 369.13933,508.715 368.39056,509.27755 368.09375,510.09375 C 367.82399,510.83551 368.03605,511.62868 368.53125,512.21875 L 366.78125,512.21875 C 366.73884,512.21408 366.69882,512.22093 366.65625,512.21875 L 366.65625,516.59375 L 366.78125,516.59375 L 368.53125,516.59375 C 367.85229,517.45345 367.83424,518.70924 368.625,519.5 C 369.47591,520.35091 370.89909,520.35091 371.75,519.5 L 375.09375,516.125 C 375.12672,516.09552 375.15802,516.06422 375.1875,516.03125 C 375.21972,516.01191 375.25101,515.99105 375.28125,515.96875 C 375.28162,515.96839 375.49976,515.68796 375.5,515.6875 C 375.50005,515.68741 375.49338,515.64282 375.5,515.625 C 375.5011,515.62203 375.53002,515.62832 375.53125,515.625 C 375.57039,515.57293 375.58228,515.57321 375.625,515.5 C 375.76199,515.26524 375.79184,515.12809 375.78125,515.15625 C 375.81807,515.06473 375.79977,515.04374 375.8125,515 C 375.82311,514.98978 375.83353,514.97936 375.84375,514.96875 C 375.90379,514.74477 375.93181,514.45186 375.90625,514.1875 C 375.89266,513.98387 375.84739,513.88985 375.84375,513.875 C 375.84389,513.86458 375.84389,513.85417 375.84375,513.84375 C 375.86975,513.94071 375.85901,513.85978 375.75,513.59375 C 375.69753,513.46336 375.66014,513.37439 375.625,513.3125 C 375.57262,513.22275 375.49154,513.05015 375.28125,512.84375 L 371.75,509.3125 C 371.29355,508.82579 370.66491,508.60087 370,508.65625 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path51990"
d="M 366.65625,515.40625 L 371.28125,515.40625 L 369.46875,517.21875 C 369.0718,517.6157 369.0718,518.2593 369.46875,518.65625 C 369.8657,519.0532 370.5093,519.0532 370.90625,518.65625 L 374.34375,515.1875 L 374.4375,515.125 C 374.44343,515.11918 374.43171,515.09972 374.4375,515.09375 C 374.49291,515.03659 374.5526,514.97676 374.59375,514.90625 C 374.62239,514.85717 374.63663,514.80216 374.65625,514.75 C 374.66861,514.71928 374.67831,514.68783 374.6875,514.65625 C 374.71862,514.54015 374.73024,514.43132 374.71875,514.3125 C 374.71489,514.25466 374.70138,514.21285 374.6875,514.15625 C 374.6766,514.1156 374.67237,514.07059 374.65625,514.03125 C 374.63982,513.99042 374.61578,513.94505 374.59375,513.90625 C 374.5483,513.82838 374.50015,513.74899 374.4375,513.6875 L 370.90625,510.15625 C 370.69734,509.93349 370.39809,509.8184 370.09375,509.84375 C 369.69897,509.8707 369.35398,510.12813 369.21875,510.5 C 369.08351,510.87187 369.18349,511.28826 369.46875,511.5625 L 371.34375,513.40625 L 366.65625,513.40625"
style="fill:#49c2f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</marker>
<marker
id="marker72805"
orient="auto"
markerHeight="4.5568175"
markerWidth="4.0334239">
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path18057"
d="M -2.0167119,0.50456824 L 0.29578813,0.50456824 L -0.61046187,1.4108182 C -0.80893187,1.6092982 -0.80893187,1.9310982 -0.61046187,2.1295682 C -0.41198187,2.3280482 -0.090181874,2.3280482 0.10828813,2.1295682 L 1.8270381,0.39519824 L 1.8739181,0.36394824 C 1.8768781,0.36103824 1.8710181,0.35130824 1.8739181,0.34831824 C 1.9016181,0.31973824 1.9314681,0.28982824 1.9520381,0.25456824 C 1.9663581,0.23002824 1.9734781,0.20252824 1.9832881,0.17644824 C 1.9894681,0.16108824 1.9943181,0.14535824 1.9989181,0.12956824 C 2.0144781,0.07151824 2.0202881,0.01710824 2.0145381,-0.04230176 C 2.0126081,-0.07122176 2.0058581,-0.09213176 1.9989181,-0.12043176 C 1.9934681,-0.14075176 1.9913481,-0.16326176 1.9832881,-0.18293176 C 1.9750781,-0.20334176 1.9630581,-0.22603176 1.9520381,-0.24543176 C 1.9293181,-0.28436176 1.9052381,-0.32406176 1.8739181,-0.35480176 L 0.10828813,-2.1204318 C 0.003838126,-2.2318118 -0.14579187,-2.2893518 -0.29796187,-2.2766818 C -0.49535187,-2.2632018 -0.66784187,-2.1344918 -0.73546187,-1.9485518 C -0.80308187,-1.7626218 -0.75309187,-1.5544218 -0.61046187,-1.4173018 L 0.32703813,-0.49543176 L -2.0167119,-0.49543176"
style="fill:#f39300;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</marker>
<marker
id="marker72808"
orient="auto"
markerHeight="4.5568123"
markerWidth="4.0334177">
<path
sodipodi:nodetypes="cccscccsssssssscccsccc"
id="path72801"
d="M -2.016709,0.50457301 L 0.29579105,0.50457301 L -0.61045895,1.410823 C -0.80893895,1.609293 -0.80893895,1.931093 -0.61045895,2.129573 C -0.41198895,2.328043 -0.090188953,2.328043 0.10829105,2.129573 L 1.827041,0.39519301 L 1.873911,0.36394301 C 1.876881,0.36103301 1.871021,0.35130301 1.873911,0.34832301 C 1.901621,0.31974301 1.931461,0.28982301 1.952041,0.25457301 C 1.966361,0.23003301 1.973481,0.20252301 1.983291,0.17644301 C 1.989471,0.16108301 1.994321,0.14536301 1.998911,0.12957301 C 2.014471,0.071523013 2.020281,0.017103013 2.014541,-0.042306987 C 2.012611,-0.071226987 2.005851,-0.092126987 1.998911,-0.12042699 C 1.993461,-0.14075699 1.991351,-0.16325699 1.983291,-0.18292699 C 1.975071,-0.20334699 1.963051,-0.22602699 1.952041,-0.24542699 C 1.929311,-0.28436699 1.905241,-0.32405699 1.873911,-0.35480699 L 0.10829105,-2.120427 C 0.003831047,-2.231807 -0.14578895,-2.289357 -0.29795895,-2.276677 C -0.49534895,-2.263207 -0.66784895,-2.134487 -0.73545895,-1.948557 C -0.80307895,-1.762617 -0.75308895,-1.554427 -0.61045895,-1.417307 L 0.32704105,-0.49542699 L -2.016709,-0.49542699"
style="fill:#d9d9cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</marker>
<marker
style="overflow:visible"
id="DotSuN"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuN">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill:#f39300;fill-rule:evenodd;stroke:#f39300;stroke-width:1pt;marker-start:none;marker-end:none"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path81580" />
</marker>
<marker
style="overflow:visible"
id="DotSuNS"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuNS">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path5020" />
</marker>
<marker
style="overflow:visible"
id="DotSuNSX"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuNSX">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path5565" />
</marker>
<marker
style="overflow:visible"
id="DotSuN4"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuN4">
<path
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="marker-end:none;fill-rule:evenodd;marker-start:none;stroke:#49c2f1;stroke-width:1pt;fill:#49c2f1"
d="M -2.5,-1 C -2.5,1.76 -4.74,4 -7.5,4 C -10.26,4 -12.5,1.76 -12.5,-1 C -12.5,-3.76 -10.26,-6 -7.5,-6 C -4.74,-6 -2.5,-3.76 -2.5,-1 z"
id="path5568" />
</marker>
<marker
style="overflow:visible"
id="DotSuNSX-5"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuNSX">
<path
inkscape:connector-curvature="0"
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none"
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
id="path5565-5" />
</marker>
<marker
style="overflow:visible"
id="DotSuN4-0"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="DotSuN4">
<path
inkscape:connector-curvature="0"
transform="matrix(0.2,0,0,0.2,1.48,0.2)"
style="fill:#49c2f1;fill-rule:evenodd;stroke:#49c2f1;stroke-width:1pt;marker-start:none;marker-end:none"
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
id="path5568-1" />
</marker>
</defs>
<metadata
id="metadata2480">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<flowRoot
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold"
id="flowRoot2485"
xml:space="preserve"><flowRegion
id="flowRegion2487"><rect
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold"
y="238.07646"
x="262.85715"
height="120"
width="184.28572"
id="rect2489" /></flowRegion><flowPara
id="flowPara2491" /></flowRoot> <g
transform="translate(-3.5714286,23.214286)"
id="g3178" />
<g
transform="translate(287.00786,159.44882)"
id="g3820">
<rect
style="fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3822"
width="99.212593"
height="56.692913"
x="14.173247"
y="237.40155"
ry="3.7880721" />
<flowRoot
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold"
id="flowRoot3824"
transform="translate(20.586428,253.63916)"><flowRegion
id="flowRegion3826" /><flowPara
id="flowPara3830">Country</flowPara></flowRoot> <text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="21.095966"
y="269.65045"
id="text84151"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447343"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
id="tspan84153"
x="21.095966"
y="269.65045">id : Long</tspan><tspan
sodipodi:role="line"
x="21.095966"
y="282.15045"
id="tspan3271">name : String</tspan></text>
</g>
<flowRoot
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
id="flowRoot8724"
xml:space="preserve"><flowRegion
id="flowRegion8726"><rect
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
y="752.14441"
x="39.286312"
height="22.868153"
width="29.904507"
id="rect8728" /></flowRegion><flowPara
id="flowPara8730" /></flowRoot> <g
transform="matrix(0.5,0,0,0.5,103.34299,0.7940752)"
id="g18053" />
<g
transform="translate(464.17321,159.44882)"
id="g3820-6">
<rect
style="fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3822-3"
width="95.669289"
height="67.322838"
x="14.173247"
y="237.40155"
ry="3.7880721" />
<flowRoot
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Helvetica Rounded LT Std;-inkscape-font-specification:Helvetica Rounded LT Std Bold"
id="flowRoot3824-6"
transform="translate(20.586428,253.57675)"><flowRegion
id="flowRegion3826-8" /><flowPara
id="flowPara3830-4">Person</flowPara></flowRoot> <text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="24.803171"
y="269.29132"
id="text84151-6"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447348"
inkscape:transform-center-y="1.4910597"><tspan
sodipodi:role="line"
id="tspan84153-6"
x="24.803171"
y="269.29132">id : Long</tspan><tspan
sodipodi:role="line"
x="24.803171"
y="281.79132"
id="tspan3316">name : String</tspan><tspan
sodipodi:role="line"
x="24.803171"
y="294.29132"
id="tspan3328">age : Integer</tspan></text>
</g>
<g
id="g5797"
transform="translate(0,1.7716289)">
<path
transform="matrix(1.2499999,0,0,1.2499999,-108.95668,-114.27159)"
sodipodi:open="true"
sodipodi:end="6.2827149"
sodipodi:start="0"
d="m 414.56693,428.74014 c 0,3.91383 -3.17278,7.08662 -7.08661,7.08662 -3.91383,0 -7.08662,-3.17279 -7.08662,-7.08662 0,-3.91383 3.17279,-7.08661 7.08662,-7.08661 3.91252,0 7.08477,3.17075 7.08661,7.08328"
sodipodi:ry="7.0866141"
sodipodi:rx="7.0866141"
sodipodi:cy="428.74014"
sodipodi:cx="407.48032"
id="path5752"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
transform="matrix(1.2499999,0,0,1.2499999,-31.003898,-114.27159)"
sodipodi:open="true"
sodipodi:end="6.2827149"
sodipodi:start="0"
d="m 414.56693,428.74014 c 0,3.91383 -3.17278,7.08662 -7.08661,7.08662 -3.91383,0 -7.08662,-3.17279 -7.08662,-7.08662 0,-3.91383 3.17279,-7.08661 7.08662,-7.08661 3.91252,0 7.08477,3.17075 7.08661,7.08328"
sodipodi:ry="7.0866141"
sodipodi:rx="7.0866141"
sodipodi:cy="428.74014"
sodipodi:cx="407.48032"
id="path5752-0"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
inkscape:connector-curvature="0"
id="path3375"
d="m 478.34646,421.65352 -77.95276,0"
style="fill:none;stroke:#49c2f1;stroke-width:5.31496048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotSuNSX);marker-end:url(#DotSuN4)"
sodipodi:nodetypes="cc" />
</g>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="402.35632"
y="414.56689"
id="text84151-4"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447431"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
x="402.35632"
y="414.56689"
id="tspan3271-2">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="468.04114"
y="414.56689"
id="text84151-4-0"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447343"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
x="468.04114"
y="414.56689"
id="tspan3271-2-4">n</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="432.50925"
y="437.64047"
id="text84151-4-4-7-2"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447343"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
x="432.50925"
y="437.64047"
id="tspan3271-2-9-1-2">+persons</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="402.54776"
y="400.80167"
id="text84151-4-4-7-2-7"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447343"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
x="402.54776"
y="400.80167"
id="tspan3271-2-9-1-2-7">+country</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#49c2f1;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Helvetica LT Std;-inkscape-font-specification:Helvetica LT Std Light"
x="426.82224"
y="416.52689"
id="text84151-4-4-7-2-7-9"
sodipodi:linespacing="125%"
inkscape:transform-center-x="7.0447343"
inkscape:transform-center-y="1.4910516"><tspan
sodipodi:role="line"
x="426.82224"
y="416.52689"
id="tspan3271-2-9-1-2-7-1">«has»</tspan></text>
</g>
</svg>

+ 0
- 1504
documentation/jpacontainer/original-drawings/jpa-mapping-graphic.svg
File diff suppressed because it is too large
View File


+ 0
- 1428
documentation/jpacontainer/original-drawings/jpa-mapping.svg
File diff suppressed because it is too large
View File


+ 0
- 1069
documentation/jpacontainer/original-drawings/three-layer-architecture.svg
File diff suppressed because it is too large
View File


Loading…
Cancel
Save