jtransfo quickie at javazone 2015
TRANSCRIPT
converting between transfer and domain objects
Joachim Van der Auwera
What is a tranfer object
Class with only getters and setters
Project Lombok recommended
@DataPublic class PersonTo { private String firstName; private String lastName; private String gender; private String birthday;}
Why use transfer objects
Decouple API and domain model
Manage application boundaries (e.g. transactions)
@Data@EntityPublic class Person { @Id Private Long id; @Basic private String firstName; @Basic private String lastName; @Basic private Gender gender; @Basic private LocalDate birthday;}
How?
Stupid boilerplate conversion code
Public Person toDomain( PersonTo to) { Person res = new Person();
Res.setFirstName( to.getFirstName()); ... Return res;}
Not always simple...
Null checks
Domain lookup
Type conversion
Still boilerplate !
Gender gender;if (StringUtils. isBlank(to.getGender)) { Gender = null;} else { Gender = Gender.valueOf( to.getGender());}res.setGender(gender);
In the real world...
Project for Flemish Government, REST API
almost 10% of the code was custom conversion between TO and domain objects
Inconsistent conversion behaviour
Stupid work, easy to make mistakes
Testing
Automate
Automatic conversion...
jTransfo
dozer
jTransfo features
Easy to use
Annotation based
No dependencies
Many transfer objects one domain object
Security enabled
Integrations
Spring framework
CDI
Joda-time
Hibernate
JRebel
Works well with Project Lombok (highly recommended!)
Easy conversion
JTransfo jTransfo = new JTransfoImpl();SomeDomain domainObject = jTransfo. convertTo(transferObject, SomeDomain.class);
SomeDomain domainObject = new SomeDomain();jTransfo.convert(transferObject, domainObject);
List list = jTransfo. convertList(transferObjects, SomeDomain.class);
Easy conversion
@Data@DomainClass("pkg.Person")public class PersonTo { private String name;
@MappedBy(field = country, path = addr) private String addrCountry;
@MappedBy(readOnly = true) private String gender;
@NotMapped private String globaalNummer;}
@MapOnlies({ @MapOnly("create"), @MapOnly(value = "*", readOnly = true)})private String somefield;
Security
jTransfo.convertTo(transferObject, SomeDomainClass.class, create, admin);
Type conversion and lists
@MappedBy(typeConverter = "filterToList")private List filters;
@MappedBy(typeConverter = "readOnlyDomain")private LayerTo layer;
Type conversion, Spring config
ORM link, object finder
Automatically build new / linked object
Find in Hibernate maybe
Always consistent
Use ReadOnlyDomain to either update links only or linked object contents as well
Inheritance support
Declare child types to convert to correct object
Normal annotations on child classes (correct domain class)
@DomainClass(value = "pkg.ObjectDomain")@DomainClassDelegate(delegates = { SomeChildTo.class, OtherChildTo.class})public class ObjectTo {
Convert interceptor
Set method to call on each convert invocation
Validations
Side effects
T convert( Object source, T target, boolean isTargetTo, ConvertSourceTarget next, String... tags);
www.jtransfo.org
https://github.com/joachimvda/jtransfo
@joachimvda
@eliwan_be
@joachimvda
@eliwan_be
@joachimvda
#DV13jTransfo
@joachimvda
#DV13jTransfo
Demo
@joachimvda
#DV13jTransfo