Binding business data to vaadin components
-
Upload
peter-lehto -
Category
Presentations & Public Speaking
-
view
286 -
download
3
Transcript of Binding business data to vaadin components
Binding business data to Vaadin components
Best practices
Peter Lehto Senior Vaadin Expert
@peter_lehto
<<UI module>>
CustomerView ProductView
<<Backend module>>
<<Commons module>>
DTOService CustomerDTO
EntityService
CustomerDTO
DTOServiceBean
DevDayUI
Client Browser
CustomerView ProductView
PersistenceUnit
DTOService
Converters EntityService
DevDayUI
Client Browser
CustomerView ProductView
PersistenceUnit
DTOService
Converters EntityService
@Localpublic interface EntityService {
void storeEntity(AbstractEntity entity);
<E extends AbstractEntity> List<E> getAll(Class<E> entityType);}
@Localpublic interface EntityService {
void storeEntity(AbstractEntity entity);
<E extends AbstractEntity> List<E> getAll(Class<E> entityType);
<E extends AbstractEntity> E getEntityById(long id, Class<E> entityType);
<E extends AbstractEntity> List<E> getPagedEntities(Class<E> entityType,int startIndex, int items, Object[] sortPropertyIds, boolean[] sortStates);
}
@Localpublic interface DTOService {
<DTO extends AbstractDTOWithIdentity> List<DTO> getAllDtos(Class<DTO> dtoType);
}
@Localpublic interface DTOService {
<DTO extends AbstractDTOWithIdentity> List<DTO> getAllDtos(Class<DTO> dtoType);
<DTO extends AbstractDTOWithIdentity> List<DTO> getPagedDtos(Class<DTO> dtoType, int startIndex, int items, Object[] sortPropertyIds, boolean[] sortStates);
<DTO extends AbstractDTOWithIdentity> long getCount(Class<DTO> dtoType);
}
@Localpublic interface DTOService {
<DTO extends AbstractDTOWithIdentity> List<DTO> getAllDtos(Class<DTO> dtoType);
<DTO extends AbstractDTOWithIdentity> List<DTO> getPagedDtos(Class<DTO> dtoType, int startIndex, int items, Object[] sortPropertyIds, boolean[] sortStates);
<DTO extends AbstractDTOWithIdentity> long getCount(Class<DTO> dtoType);
<DTO extends AbstractDTOWithIdentity> DTO getDtoById(long itemId, Class<DTO> dtoType);
<DTO extends AbstractDTOWithIdentity> void storeDto(DTO dto);}
@Statelesspublic class DTOServiceBean implements DTOService, EntityService {
@PersistenceContext(unitName = "devday")private EntityManager entityManager;
…}
POJO built by DTOService
Minimal ondemand data item
Free from Entity model changes
DTO (DataTransferObject)
POJO built by DTOService
Minimal ondemand data item
Free from Entity model changes
No referenced property loading concerns
DTO (DataTransferObject)
UI needs DTOs
Backend knows about entities
Converter per DTO / usecase type
Entity <-> DTO Conversion
public interface EntityToDTOConverter {
AbstractDTOWithIdentity convertToDTO(AbstractEntity entity);
Class<? extends AbstractEntity> getEntityType();
Class<? extends AbstractDTOWithIdentity> getDTOType();}
public interface EntityToDTOConverter {
AbstractDTOWithIdentity convertToDTO(AbstractEntity entity);
Class<? extends AbstractEntity> getEntityType();
Class<? extends AbstractDTOWithIdentity> getDTOType();}
public interface DTOToEntityConverter {
<DTO extends AbstractDTOWithIdentity, E extends AbstractEntity> E convertToEntity(DTO dto);
Class<? extends AbstractEntity> getEntityType();
Class<? extends AbstractDTOWithIdentity> getDTOType();
}
@Retention(RUNTIME)@Target(TYPE)@Qualifierpublic @Interface DTOType {
Class<? extends AbstractDTO> value(); }
@DTOType(CustomerListingDTO.class)public class CustomerEntityToListingDTOConverter implements EntityToDTOConverter {
@Overridepublic Class<CustomerEntity> getEntityType() {
return CustomerEntity.class;}
@Overridepublic Class<CustomerListingDTO> getDTOType() {
return CustomerListingDTO.class;}
@Overridepublic CustomerListingDTO convertToDTO(CustomerEntity e) { …
}}
public class DTOTypeAnnotationLiteral extends AnnotationLiteral<DTOType> implements DTOType {
private Class<? extends AbstractDTO> dtoType;
public DTOTypeAnnotationLiteral(Class<? extends AbstractDTO> dtoType) {this.dtoType = dtoType;
}
@Overridepublic Class<? extends AbstractDTO> value() {
return dtoType;}
}
protected EntityToDTOConverter findEntityToDTOConverter( Class<? extends AbstractDTO> dtoType) {
Instance<EntityToDTOConverter> converterSelection = converterInstantiator.select(new DTOTypeAnnotationLiteral(dtoType));
if (converterSelection.isAmbiguous()) {// more than one converter for same type exception…
}if (converterSelection.isUnsatisfied()) {
// no converter available exception}
return converterSelection.get();}
No need to change code
Add new converters for new DTO types
Converters via bean discovery
DTOService + Converter
No need to change code
Add new converters for new DTO types
Converters via bean discovery
UI knows and works only with DTOs
DTOService + Converter
In memory containers
HierarchicalContainer – IndexedContainer that supports parent/child relationships
IndexedContainer – Basic container that is manually built
In memory containers
BeanItemContainer – A container that is automatically built from a collection of Java Beans
HierarchicalContainer – IndexedContainer that supports parent/child relationships
IndexedContainer – Basic container that is manually built
Add-on from Vaadin Directory
Retrieve data by index
Will not expose backend assets
LazyQueryContainer
Grid grid = new Grid();container = new LazyQueryContainer(queryFactory, PRIMARY_KEY_PROPERTY, BATCH_SIZE);grid.setContainerDataSource(container);
public class LazyDTOQuery<DTO extends AbstractDTO> extends AbstractBeanQuery<DTO> {
private Class<DTO> dtoType;private DTOService dtoService;
public LazyDTOQuery(Class<DTO> dtoType, DTOService dtoService, QueryDefinition queryDefinition) {
super(…);}
@Overrideprotected List<DTO> loadBeans(int startIndex, int numItems) {
return dtoService.getPagedDtos(dtoType, startIndex, numItems, getSortPropertyIds(), getSortStates());
}
@Overridepublic int size() {
return dtoService.getCount(dtoType);}
…}
Fields are Components with databinding
Fields can be bound to properties
Group of properties is an Item
Vaadin Fields
public class Person {
private String name;private int age;
// Getters and setters omitted
}
BeanItem<Person> item = new BeanItem<Person>(person);
public class Person {
private String name;private int age;
// Getters and setters omitted
}
BeanItem<Person> item = new BeanItem<Person>(person);
Property ID Type Value
“name” String.class “John Doe”
“age” Integer.class 42
public class Person {
private String name;private int age;
// Getters and setters omitted
}
BeanItem<Person> item = new BeanItem<Person>(person);
Property ID Type Value
“name” String.class “John Doe”
“age” Integer.class 42
Buff
eri
ng
Data source
UI Logic
AbstractField
Button
Browser
TextField value change
Save button pressed
Buff
eri
ng
Data source
UI Logic
AbstractField
Button
Browser
TextField value change
Save button pressed
ClickEvent
commit()
Buff
eri
ng
Data source
UI Logic
AbstractField
Button
Browser
TextField value change
Save button pressed
ClickEvent
commit()
Buff
eri
ng
Data source
UI Logic
AbstractField
Button
Browser
TextField value change
Save button pressed
ClickEvent