Reputation: 889
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
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
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
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