Seyf
Seyf

Reputation: 889

When to have a DTO layer?

I am developing a web application with AngularJS for the front-end and Java Play Framework for the back-end services. For database access I use Hibernate.

So far I have about 30 services which consume and produce JSON, and I send Hibernate objects directly instead of having a data transfer layer.

Currently I am facing recursive call issues because of two-way referencing of Hibernate entities. Those issues are already solved by some annotations and JSON Views, however configuration of those views for different service methods is becoming a real issue and annotating the entities accordingly for JSON conversion is really bloating the lovely simple entity objects.

Currently I am thinking of a DTO layer to ease the communication, however I am not sure if the development and performance overhead caused by preparing request and response DTO objects for each service really worth it. Is it a good idea?

Upvotes: 4

Views: 1270

Answers (3)

K.Nicholas
K.Nicholas

Reputation: 11551

I have taken the approach of writing a XSD schema definition for the DTO objects and then using a plugin to generate the actual POJOs. In my entities I add toEntityType and fromEntityType translation methods. This couples DTO translation directly to the entity and controlling services. I don't need to write the POJOs and the XSD serves as documentation. E.g. an Entity

public class Product {
    private Long id;
    private String name;

    /**
     * Fill out properties from PurchaseOrderType. Copies all dependencies.   
     * @param productType {@link ProductType}
     * @return Product
     */
    public Product fromProductType(ProductType productType) {
        this.id = productType.getId();
        this.name = productType.getName();
        return this;
    }

    /**
     * Create and return ProductType representation. 
     * @return {@link ProductType}
     */
    public ProductType asProductType() {
        ProductType productType = new ProductType(); 
        productType.setId(id);
        productType.setName(name);
        return productType;
    }
    ... getters, setters, 
}

an XSD definition:

<!-- product -->
<xsd:element name="productType">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="id" type="xsd:long" minOccurs="0"/>
            <xsd:element name="name" type="xsd:string" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

In pom.xml

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.13.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

and a service

/**
 * Rest endpoint for a ProductType
 * rest/productservice/getproduct/{id}
 * @param id @{link Long}
 * @return {@link ProductType}
 */
@GET
@Path("getproduct/{id}")
@Produces({MediaType.APPLICATION_JSON})
public ProductType getProduct(@PathParam("id") Long id) throws Exception {
    // retrieve product information based on the id supplied in the formal argument
    Product getProduct = productDao.getProduct(id);
    if ( getProduct == null )
        throw new IllegalArgumentException("Product not found for id: " + id);
    ProductType productType = getProduct.asProductType();
    return productType;
}

Upvotes: 0

Amit Parashar
Amit Parashar

Reputation: 1457

DTO will use the same string pool as used by entity objects. In case you have complex objects in your entities, you can simply do shallow copying between DTO to entity and entity to DTO.

Usage of DTO will protect from exposing entity design in the service layer methods. Usage of DTO should not cause a significant performance issue.

Upvotes: 1

Christian Beikov
Christian Beikov

Reputation: 16400

Actually you could even improve your performance by making use of a DTO approach since you could query less data, assuming the DTO is not a 1:1 copy of you entity model. I wrote an article on the problems that come with using the entity model and how you can implement a DTO approach efficiently with Blaze-Persistence Entity Views. Maybe you want to give that a try and see how it can improve your design and performance!

Upvotes: 0

Related Questions