Search code examples
jsonspringentitydto

Using DTO vs Serializating entities


I have already read this thread before asking the question, but this is a pretty old thread and lots of new ways for de serializing the entities are there now.

My first question is why we should not use the Entities in the Controller ? If the only reason is waste data travelling across the wire then it should not be an issue because there are ways to avoid this.

I am using flexjson.JSONSerializer for de serializing the entity and Gson.fromJSON() for serializing the json into entity instead of using DTO. My controller code looks like this..

@RequestMapping (value = "", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public void createStream(@RequestBody String  streamData) {
    StreamEntity streamEntity = null;
    try {
        streamEntity = streamService.createStream(streamData);
        logger.info("Created Stream [id=%s, name=%s]", streamEntity.getId(), streamEntity.getStreamName());
    } catch (Exception e) {
        logger.info("Error occured while creating the stream[name=%s]: %s",streamEntity.getStreamName(), e.getMessage());
    }               
}


@RequestMapping (value = "/{id}", method = RequestMethod.GET)
public String fetchStream(@PathVariable(value = "id")final Long id) {
    StreamEntity streamEntity = streamDAO.getById(id);
    String json = StreamEntitySerializer.serialize(streamEntity);       
    return json;
}

Only purpose of using the entity in controller is for logging. Is there anything wrong/objectionable with the code ?


Solution

  • I think you have two questions....

    Question 1: Why not expose the entity to the controller (aka Presentation Layer):

    For large/complex project its bad form to use the Entity in the controller because it leads to business logic getting spread around your project. Once you pass the entity to your Presentation layer (aka Controllers), any controller can modify and save the data. Typically multiple controllers will need access to the same entities. This leads to code maintenance hell, because now you have to maintain your data CURD, anti-corruption and business logic in multiple places. Moving all your Business logic, the logic that manipulates the data, to a common package (aka Domain\Service Layer) makes maintaining the code much easier long term. By passing DTOs up the stack to the controllers, you'll end up with much cleaner code, that is much easier to test. Here is a good presentation about layered architectures : https://www.youtube.com/watch?v=aZp7C971uC8

    Other reading:

    Question 2 Why not serialize the entity vs. converting it to a DTO and serializing that.

    There are a ton of reasons not to do this, but here are the frist ones that come to mind.

    • Maintenance : By exposing your entities directly, your creating a hard link between how data is stored and the data objects your clients get. For example, what happens when you need to rename/delete a field in your entity. What happens when you change your database? Switching between MySQL and Mongodb gets a lot easier if the entities are getting converted to a DTO.

    • Testing : its much easier to mock a DTO instance than a Hibernate instance

    • Performance : Serializing an Entity can trigger all the lazy load fields to be pulled from that database, even if you don't need to expose that data. This can make tracking down performance issues hard. DTOs causes you to be explicit about which fields are transformed and serialized. Also since DTOs are normally smaller and simpler, which makes serialization faster.