Showing posts with label jDTO Binder. Show all posts
Showing posts with label jDTO Binder. Show all posts

Monday, May 6, 2013

jDTO Binder gains experimental support for compile-time config validation

One of the most frustrating things that emerge when working with a framework is misconfiguration, specially if we find out of this misconfiguration on runtime or worse, after moving the application into production.

Normally when frameworks suffer this kind of weakness, developers might decide to create IDE-specific plugins or extra tooling to prevent unwanted and unnoticed runtime misconfiguration. The object to object mapping framework I've developed (jDTO Binder) is a great tool but sadly suffers from this issue so, as part of release 1.5, I am currently developing a set of tools that aim to ease the development. The first of this tool is a compile-time annotation processor that can validate the configuration for a given DTO.

Annotation Config Validation

The great thing of compile-time annotation processors is that are able to integrate with any IDE and they're able to have the build failing if a misconfiguration is detected.

Here is how it looks jDTO Binder compile-time verifier out of the box in Netbeans IDE 7.2:


Currently this is experimental and I'm working on the idea, the specific validations that will be performed and the way this validations should manifest will emerge on the development of this idea and for the time being very experimental and limited support is implemented but hopefully it will plot on improved productivity.

In the current state the compile time verifier functionality checks and prints compile-time warnings when the source property of a given DTO field is mistyped and also encourages the user to place annotations on getters instead of on fields following a performance suggestion showed on the official documentation.

Sunday, May 20, 2012

Wicket 1.5 + Spring Framework + Hibernate + jDTO Binder Sample Application

In this post I'll go through a sample project I've created to demonstrate jDTO Binder in action with some of the most popular frameworks on the Java world. The sample project is publicly available on GitHub.

To get the project running without too much fuss, then just checkout the project, open it on netbeans 7.1.2 and hit run :)

If you're on linux or mac os X then you can do something like this:

$ git clone git://github.com/jDTOBinder/jdto-sample-projects.git
$ cd jdto-sample-projects/jdto-wicket-demo/
$ mvn clean tomcat:run

After that you may point your browser to http://localhost:8080/jdto-wicket-demo/ and that's it, you should see something like this:


The CSS3 Highlights:

The styling is pretty standard styling what can be kind of uncommon is the menu box which is rotated and it has a little shadow, also some google web fonts are being used, let's go with the easiest first, the shadow:

box-shadow: 6px 6px 5px #888;

The parameters mean in order, the horizontal distance, the vertical distance the blur distance and the shadow color.

Also you can see that the box is kind of rotated let's say 8 degrees to the left? Normally that would have been defined by using the transform property, but it seems that is still not that supported in all browsers, so I have added three rules to support webkit, mozilla and internet explorer 9:

-webkit-transform:rotate(-8deg);
-moz-transform:rotate(-8deg);
-ms-transform: rotate(-8deg);

Finally, to include some web fonts, some import statements must be added:

/* import the google web font  */
@import url(http://fonts.googleapis.com/css?family=Averia+Libre:700);
@import url(http://fonts.googleapis.com/css?family=Oxygen);

That enabled me to use the "Averia Libre" and "Oxygen" fonts on my styles.

The Wicket Highlights

Apache Wicket is a really nice web framework that you can use to build everything in Java, from websites to web applications, there are some things that may be uncommon for some developers, I've used the wicket:link tag to include css resources packaged on the classpath:

<head>
    <title>jDTO Binder Pizza Orders!</title>
    <wicket:link>
        <link rel="stylesheet" type="text/css" href="jdtopizzas.css" />
    </wicket:link>
</head>

Normally one would have had that css resource included on the java code but this wicket magic makes it more intuitive and consistent.

Another use of the tag is to link between pages, as I show in the following example:

<p>Take a look at the <wicket:link><a href="ViewOrdersPage.html">orders you have already created</a></wicket:link>.</p>

In this case, I have a ViewOrdersPage.java file and by creating the link this way, wicket takes care of pointing the href to the right place without adding extra Java code.

DTOs as the Wicket Models

Wicket extensively uses "intermediate" objects to act as the model of it components this is where DTOs come in handy, since you can modify the data they carry without affecting the data on the database, they are perfect for using them as the components model. The following code shows how you bind a wicket form with the "form" that takes the service to create a new pizza order:

PizzaOrderForm form = new PizzaOrderForm();
form.setPizzas(new ArrayList<PizzaDTO>());

//create the order form.
orderForm = new Form<PizzaOrderForm>(
        "orderForm",
        new CompoundPropertyModel<PizzaOrderForm>(form));

//for the case you want to add pizzas and you have already filled the form elements.
//this is only necessary because I left out the menu list from the form.
orderForm.add(new TextField("customerName").add(new BlurAjaxFormSubmitBehavior()));
orderForm.add(new TextField("customerPhone").add(new BlurAjaxFormSubmitBehavior()));
orderForm.add(new TextField("customerAddress").add(new BlurAjaxFormSubmitBehavior()));

With the use of CompoundPropertyModel things are really easy. I've added a behavior that submits the form data every time the field losses focus, this prevents unwanted data erasing on the client side. (Also I could have designed my page a little better hehe).

Spring and Hibernate Highlights

As this is a sample application but is intended to show real-life stuff, it uses spring framework and hibernate, but if you had to install and configure a database server to test the application, you probably wouldn't test it, so here is how I've used the H2 embedded database engine to use just your computers memory a little bit more:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:pizza"/>
</bean>

As you can see, the database connection pool has the url "jdbc:h2:mem:pizza" and that is all what it takes to tell H2 that you don't want to persist anything.

Finally, I've used a singleton bean to load the sample data when the application starts, this bean loads the list of available products.

<!-- initial data loader bean -->
<bean id="initialDataLoader" class="org.jdto.demo.InitialDataLoader" />

class InitialDataLoader {
    
    private static final Logger logger = LoggerFactory.getLogger(InitialDataLoader.class);
    
    @Autowired
    private HibernateTemplate template;
    
    @PostConstruct
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    private void init() {
        createPizzas();
    }

    private void createPizzas() {
        logger.info("Creating initial set of pizzas!");
        
        Pizza pepperoni = new Pizza("Pepperoni Pizza", 4, 8.50);
        Pizza mozzarella = new Pizza("Mozzarella Pizza", 3, 7.50);
        Pizza special = new Pizza("Special Ham Pizza", 5, 10.0);
        Pizza onion = new Pizza("Onion Pizza", 4, 9.0);
        Pizza anchovy = new Pizza("Anchovy Pizza", 2, 7.95);
        
        template.save(pepperoni);
        template.save(mozzarella);
        template.save(special);
        template.save(onion);
        template.save(anchovy);
    }
}

One of the beauties of Spring is that you can use package-scoped classes as beans so you don't expose them to the team developers (and they don't feel tempted to use them).

Since this bean will be executed on startup time we will need a brand new transaction, so I've set the propagation attribute to "requires new".

jDTO Binder Highlights

In this application, jDTO Binder takes care of copying data between domain objects and DTO objects, how it's being used is described on the project's README file.


That would be all for now, please feel free to make comments on the post and I hope you find it useful for starting a new project with this great technologies.

Sunday, March 25, 2012

Java architecture with DTOs

The DTO Discussion

The DTO (Data transfer objects) pattern is really useful if you intend to achieve a clean separation between the service layer and the presentation layer of the application. DTOs are part of the service layer API and therefore something that is best to have than not to.

DTOs also serve another purpose: Adapt model values, which in most cases are normalized, to view-friendly values, which most of the time presents particular values from an object graph and also calculated values.

Very often, applying the DTO pattern in a given architecture is not an easy task, you earn an application easy to maintain  by spending a lot of time (shallow) copying data from one object to another.

One solution for the data copy problem can be found by using a framework, in this case jDTO Binder. jDTO Binder makes easy for the programmer to achieve some tasks:


  • Receive form values and copy them to target business objects.
  • Create lists with data from particular properties of an object graph.
  • Add to those lists calculated values.
  • Change the format of the data to be more appropriate for display or network transmission.
I've taken the time to create a sample maven project with a very popular setup: Spring Web MVC, Spring Framework and Hibernate. Although you can use this project as a starting point to build a web application with this technologies, this project incorporates jDTO Binder into its ecosystem and demonstrates how it makes your life a lot easier.

To run the project, just unzip the file, open the terminal and type the following commands:

$ cd <path to the unzipped folder>
$ mvn clean install tomcat:run

Project Description and Walkthrough.


Required Skills: To go through this project, basic Spring Web MVC knowledge is required. Even though the important part is written on the service layer, Spring MVC and Spring Context knowledge helps a lot to put all the pieces together.

The DTOs

The following snippets shows the DTOs this project uses and its purpose:

public class PizzaDTO implements Serializable {
    
    @Source("id")
    private Long pizzaId;
    
    
    @Sources(value={@Source("pizzaName"), 
        @Source("price")}, merger=StringFormatMerger.class, mergerParam="%s ($ %.2f)")
    private String description;
    
    private double price;
    private int rating;
    ...
}


The first DTO to analyze is the PizzaDTO, this one is intended to serve in a listing of available pizzas. It has a description attribute which is intended for display and is created from the pizza name and the pizza price in a formatted string.

public class PizzaOrderForm implements Serializable {
    
    @NotEmpty //validation annotation
    @Source("whoOrderedName")
    private String customerName;
    
    @NotEmpty //validation
    @Source("contactNumber")
    private String customerPhone;
    
    @NotEmpty //validation
    private String customerAddress;
    
    @Size(min=1) //validation
    @DTOTransient
    private List<PizzaDTO> pizzas;
    ...
}

The second DTO is really the model of a form to take a pizza order, it does not only have DTO binding annotations but also standard JSR 303 bean validation annotations so the data can be validated automatically.

public class OrderDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private Long id;
    
    @Source("whoOrderedName")
    private String customerName;
    
    private String customerAddress;
    
    @Source("contactNumber")
    private String customerPhone;
    
    @Source(value="orderDate", merger=DateFormatMerger.class, mergerParam="MM/dd/yyyy hh:mm")
    private String orderDate;
    
    @Source(value="pizzas", merger=SumMerger.class, mergerParam="price")
    private Double orderPrice;
    ...
}

Next on the line is a DTO intended for a list of pizza orders, it contains most of the data the pizza order has but also it calculates the price of each order so you don't have to do it manually or save the amount in an extra field on your database table.

The Service Class

Now we've got to the interesting part, how the service layer takes advantage of these DTOs to make your life easier. The following is the declaration of the PizzaOrderService, I'll show separately the implementation methods so I can give a little more explanation of each without having you to scroll up and down repeatedly :).

@Service
@Transactional
class PizzaOrderServiceImpl implements PizzaOrderService, Serializable {

    private static final long serialVersionUID = 1L;
    @Autowired
    private HibernateTemplate hibernate;
    @Autowired
    private DTOBinder binder;
    @Autowired
    private Validator validator;
    
    ... //implementation goes here
}


This is a normal service class, it is transactional because it interacts with hibernate, it has injected an instance of the very helpful class HibernateTemplate, also has injected an instance of the DTOBinder (which is configured as a spring bean in applicationContext.xml), finally the JSR 303 standard bean validator to perform validations on objects (also declared as a spring bean).

This class is serializable because it may be serialized for example in a web session.

    @Override
    public List<PizzaDTO> listAvailablePizzas() {

        DetachedCriteria criteria = DetachedCriteria.forClass(Pizza.class);
        criteria.addOrder(Order.asc("pizzaName"));

        return binder.bindFromBusinessObjectList(PizzaDTO.class, hibernate.findByCriteria(criteria));
    }

This method queries the database for pizzas, and returns the list as a list of PizzaDTO by taking advantage of the DTO Binder. Please note that if we hadn't used the DTO framework, we would have had to iterate over the list returned by hibernate template and build the DTO instances ourselves by setting and formatting the values; all is taken care by the framework.

    @Override
    public boolean placeOrder(PizzaOrderForm form) {

        //may validate with hibernate validator
        if (!validator.validate(form).isEmpty()) {
            return false;
        }

        PizzaOrder order = binder.extractFromDto(PizzaOrder.class, form);


        order.setOrderDate(new Date());
        order.setPizzas(new ArrayList<Pizza>());

        for (PizzaDTO pizzaDTO : form.getPizzas()) {
            Pizza pizza = hibernate.get(Pizza.class, pizzaDTO.getPizzaId());
            order.getPizzas().add(pizza);
        }

        hibernate.save(order);

        return true;
    }

This method may look familiar to you if you had to build functionality for adding data to a database in the past :). In this case we get a PizzaOrderForm as a parameter, use the validation framework to check the data, extract the form values into a proper business object using de DTO framework, set data that was not inputted, relate the order with the actual pizzas and finally persist the order!

That's a lot for the few lines of code we've written! If we hadn't had use the DTO framework, then we would have had to manually copy each property of the form into the appropriate property of the business object, which can take several more lines.

    @Override
    public List<OrderDTO> listOrders() {
        DetachedCriteria criteria = DetachedCriteria.forClass(PizzaOrder.class);
        criteria.addOrder(Order.desc("orderDate"));

        return binder.bindFromBusinessObjectList(OrderDTO.class, hibernate.findByCriteria(criteria));
    }

The last method is much the same as the first one so no further discussion is needed.

A couple of final words.

As we may have noticed, this architecture is rather simple but full featured. It uses data validation, transactional behavior and the code is kept really small and clean thanks to the DTO Binding framework.

When used the right way, DTOs are a very powerful tool and makes our application even more bullet-proof by isolating completely the database code (persistent objects included) from the presentation tier.

Another thing to note is that, if you need to change from where data is acquired, add or remove fields is just a matter of configuring the DTO object and nothing else! Compare this to the traditional approach in which you would have added the extra field and then going through each loop when you populated the DTO and add the extra data copy operation.

Thursday, January 5, 2012

jDTO Binder 0.7 Released

I'm proud to announce the release of version 0.7 of jDTO Binder, the java framework to populate DTO objects easily.

This release includes the latest bugfixes and two new features:

Default configuration file.

The jDTO framework has the "convention over configuration" philosophy and therefore a new convention was introduced: If there is a package resource called jdto-mappings.xml on the default package, then it will use that configuration file instead of the annotations config, so now, if you're using CDI, you have the option to map your DTOs using an XML configuration file.

Read / Write Maps

The framework has gained the ability to read and write maps, so now implementations of the java.util.Map interface can be used to populate DTO's and can be populated out of objects.

The following code snippets demonstrates how to use this feature.

Map from object:

SimpleEntity entity = new SimpleEntity("myString", 23, 34.45, true);

HashMap<String, Object> map = binder.extractFromDto(HashMap.class, entity);


String strVal = (String) map.get("aString");
int intVal = (Integer) map.get("anInt");
double doubleVal = (Double) map.get("aDouble");
boolean boolVal = (Boolean) map.get("aBoolean");

Object from map:

HashMap<String, String> values = new HashMap<String, String>();

values.put("myString", "simpleString");
values.put("related.aString", "relatedString");

SimpleAssociationDTO dto = binder.bindFromBusinessObject(SimpleAssociationDTO.class, values);

These new features enables the users of the framework to explore new posibilites for example populating objects from properties files in a really elegant way.

Sunday, December 11, 2011

jDTO Binder - Immutable DTOs

jDTO Binder 0.6 is out and with one new great feature. A really good practice in java is to minimize mutability of objects and with this you gain thread safety and also you can optimize memory by creating an instance pool; jDTO Binder can now instantiate objects by using a constructor other than the default and therefore making possible immutable DTO's

In order to take advantage of this feature, your DTO class should have one or more constructors with arguments and none default constructor. Also since some limitations of the Java Reflection API you need to configure each constructor argument to specify which will be the source value.

The following is an example of an immutable DTO:
public final class SimpleImmutableDTO {
    private final String firstString;
    private final String secondString;
    
    //make this the DTO constructor.
    @DTOConstructor
    public SimpleImmutableDTO(@Source("myString") String firstString, @Source("related.aString") String secondString) {
        this.firstString = firstString;
        this.secondString = secondString;
    }
    
    public SimpleImmutableDTO(String firstString, String secondString, String thirdString) {
        this.firstString = firstString;
        this.secondString = secondString;
    }
    
    public String getFirstString() {
        return firstString;
    }

    public String getSecondString() {
        return secondString;
    }
    
}

Immutable DTOs can take advantage of all of the features regular DTOs can except for "transient" constructor arguments which at the time doesn't make sense to me.

Also this feature is enabled for XML configuration:
<dto type="com.juancavallotti.jdto.dtos.SimpleImmutableDTO">
    <immutableConstructor>
        <arg type="java.lang.String">
            <source name="myString" />
        </arg>
        <arg type="java.lang.String">
            <source name="related.aString" />
        </arg>
    </immutableConstructor>
</dto>

Sunday, October 30, 2011

jDTO Binder - Java DTO Framework

DTO design pattern is mainly used to make a clean separation between layers. The DTO objects are meant to be part of the API of each application layer. Even though they're quite good on separation, they do have some costs associated: If not well managed, you'd probably end up by having lots of them, sometimes with mostly the same attributes between one another; on the other hand you might mitigate this by making a huge DTO with lots of information but ending up with the loss of lazy loading from the persistence layer. The previous costs must be managed by the developer and there's not much a framework can do besides generating the DTO classes, which have it's own disadvantages.

One really painful thing about using the DTO pattern is that the developer must take care of copying the data from one side to another and that's where jDTO Binder framework comes in handy. This framework is also an implementation of a bigger concept which I like to call "Object to Object Mapping" or simply OOM, and this concept is vey similar to another related and existing concepts like Object Relational Mapping (ORM) and Object XML Mapping (OXM).

This framework is still under development, but is quite stable to be used in production environments, in fact it is being used successfully on production environments.

The url for the full documentation can be found here:
https://github.com/juancavallotti/jDTO-Binder/wiki/jDTO-Binder---Java-DTO-framework.

And here's how to get started:

An example project can be found for download here.

First of all, we need to add the dependencies to our pom.xml file:

<dependency>
    <groupId>com.juancavallotti</groupId>
    <artifactId>jdto</artifactId>
    <version>0.4</version>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.2</version>
</dependency>

I've decided the framework shouldn't have too many dependencies, so I've picked up those which must be (IMHO) in every serious java project:

  • SLF4J - So you can log the output with your favorite logger.
  • Commons Lang - This library is really useful, so if you're not using it, you should!

And also the repository to get jDTO:

    <repositories>
        <repository>
            <id>com. juancavallotti</id> 
            <name>jdto</name> 
            <url>http://juancavallotti.com/maven2</url> 
            <layout>default</layout>
        </repository>    
    </repositories>

Next we need to create some classes to act as source business objects, note that jDTO uses the property accessor methods (AKA getters and setters) to read property values from source beans, you should consider this and you can take advantage of this fact because you can read information without necessarily accessing a field.

A typical person class:

public class Person  implements Serializable {
    private long id;
    private String firstName;
    private String lastName;
    private Date birthDay;
    //GETTERS AND SETTERS
}

And a bill class with it's items:

public class Bill {
    private String clientName;
    private Date billExpiration;
    private List<BillItem> items;
    //GETTERS AND SETTERS
}

public class BillItem {
    private String itemName;
    private double price;
    private int amount;
    private double taxPercentage;
    //GETTERS AND SETTERS
}

These classes are used to show some of the features of the framework.

So we're now ready to start filling out some DTO's.

First we'll take a look a the PersonDTO, this one is rather simple, but it shows some of the key features of jDTO framework, binding by convention (default behavior), formatting fields and composing one field out of multiple fields:

public class PersonDTO implements Serializable {
    
    //bound by convention
    private long id;
    
    @Source(value="birthDay", merger=DateFormatMerger.class, 
            mergerParam="dd/MM/yyyy")
    private String birthday;
    
    @Sources(value={@Source("firstName"), @Source("lastName")}, 
            merger=StringFormatMerger.class, mergerParam="%s %s")
    private String fullName;
    //GETTERS AND SETTERS
}

And finally, we use the framework to bind the data:

DTOBinder binder = DTOBinderFactory.getBinder();

//bind a person to a person DTO
Person person = SampleData.samplePerson();
PersonDTO dto = binder.bindFromBusinessObject(PersonDTO.class, person);

It's really recommended you keep the DTOBinder instance as a singleton, so for that matter, the framework already provides you this facility, you  only need to call DTOBinderFactory.getBinder() and it's all done for you.

Next, we may want to build a DTO out of a bill but this time we just want the customer name and the amount of money the bill is worth, so here is how the DTO looks like:
public class BillDTO {
    
    //bound by convention
    private String clientName;
        
    @Source(value="items", merger=SumExpressionMerger.class, 
            mergerParam="(price * amount) * (1 + taxPercentage*0.01)")
    private double billTotalPrice;
    //GETTERS AND SETTERS
}

The final application code looks like:

public static void main(String[] args) {
        
    //get an instance of a singleton binder
    DTOBinder binder = DTOBinderFactory.getBinder();
    
    //bind a person to a person DTO
    Person person = SampleData.samplePerson();
    PersonDTO dto = binder.bindFromBusinessObject(PersonDTO.class, person);
    
    System.out.println(dto);
        
    
    Bill bill = SampleData.sampleBill();
    BillDTO billdto = binder.bindFromBusinessObject(BillDTO.class, bill);
    
    System.out.println(billdto);
}

And the output is:
PersonDTO{id=1, birthday=30/10/1982, fullName=Michael Princeton}
BillDTO{clientName=I'm a Client, billTotalPrice=22.0}

This is all for this small tutorial, please feel free to submit bug reports or feature requests on the issue tracker of the github project.