Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
book-of-vaadin.pdf
Скачиваний:
88
Добавлен:
24.03.2015
Размер:
13.43 Mб
Скачать

Vaadin JPAContainer

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

Table 21.2. QueryModifierDelegate Methods

queryWillBeBuilt()

orderByWillBeAdded()

orderByWasAdded()

filtersWillBeAdded()

filtersWereAdded() queryHasBeenBuilt()

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

You can use the getRoots().iterator().next() in CriteriaQuery to get the "root" that is queried, for example, the PERSON table, etc.

21.7.1. Filtering the Query

Let us consider a case where we modify the query for a Person container so that it includes only people over 116. This trivial example is identical to the one given earlier using the 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));

}

});

21.7.2. Compatibility

When building queries, you should consider the capabilities of the different JPA implementations. Regarding Hibernate, see Section 21.9.3, “Joins in Hibernate vs EclipseLink”.

21.8. Automatic Form Generation

The JPAContainer FieldFactory is an implementation of the FormFieldFactory and TableFieldFactory interfaces that can generate fields based on JPA annotations in a POJO. It goes further than the 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.

470

Filtering the Query

Vaadin JPAContainer

The generated defaults are as follows:

 

Annotation

Class Mapping

@ManyToOne

NativeSelect

@OneToOne, @Embedded

Nested Form

@OneToMany, @ElementCollection

MasterDetailEditor (see below)

@ManyToMany

Selectable Table

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

21.8.1. Configuring the Field Factory

The FieldFactory is highly configurable with various configuration settings and by extending.

The setMultiSelectType() and setSingleSelectType() allow you to specify a selection component that is used instead of the default for a field with @ManyToMany and @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 AbstractSelect.

The 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.

21.8.2. Using the Field Factory

The most basic use case for the JPAContainer FieldFactory is with a 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 Select countrySelect = new Select("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.setWriteThrough(false); // Enable buffering countryForm.setEnabled(false);

// When an item is selected from the list...

countrySelect.addListener(new ValueChangeListener() { @Override

public void valueChange(ValueChangeEvent event) { // Get the item to edit in the form

Item countryItem =

Configuring the Field Factory

471

Vaadin JPAContainer

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.addListener(new ClickListener() {

@Override

public void buttonClick(ClickEvent event) { try {

countryForm.commit();

countryForm.setEnabled(false); } catch (InvalidValueException e) {

}

}

});

}

});

countrySelect.setImmediate(true);

countrySelect.setNullSelectionAllowed(false);

This would create a form shown in Figure 21.6, “Using FieldFactory with One-to-Many Relationship”.

Figure 21.6. Using FieldFactory with One-to-Many Relationship

If you use Hibernate, you also need to pass an EntityManagerPerRequestHelper, either for the constructor or with setEntityManagerPerRequestHelper(), as described in Section 21.9.2, “The EntityManager-Per-Request pattern”.

472

Using the Field Factory

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]