diff options
Diffstat (limited to 'documentation/jpacontainer/jpacontainer-usage.asciidoc')
-rw-r--r-- | documentation/jpacontainer/jpacontainer-usage.asciidoc | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/documentation/jpacontainer/jpacontainer-usage.asciidoc b/documentation/jpacontainer/jpacontainer-usage.asciidoc deleted file mode 100644 index c4ba3b2a3f..0000000000 --- a/documentation/jpacontainer/jpacontainer-usage.asciidoc +++ /dev/null @@ -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"]. - - - - - |