5

We're to use DTO's to send data to and from the presentation layer. We have layers like:

  • facade
  • appService
  • domain

And We have use Dozer to help us convert entity to dto. But i have 2 question now:

  1. from entity to dto we can use dozer, but from dto to entity can we use dozer? If Yes, How?
  2. Where shoud i create entity? in facade or DTOAssembler?

for example,I have to register a book. the book Entity look's like:

Book{
   public Book(BookNumber number,String name){
      //make sure every book has a business number,
      //and the number can't change once the book is created.
      this.bookNumber = number;
      ..
   }
}

and we hav a DTOAssembler:

BookDTOAssembler{

  BookDTO toDAO(bookEntity){
  ...
  }
  BookEntiy fromDTO(book DTO,BookRepository bookRepository){
    //1.Where should i create book entity? 
    //2.Is there any effective way to convert dto to entity in java world?
  }
}

option 1

the BookManagedFacade has a registerBook function:
public registerBook(bookDTO){
   Book book = BookDTOAssembler.fromDTO(book DTO);
}

//Create book in BookDTOAssembler.fromDTO 
public static BookEntiy fromDTO(BookDTO bookDTO,BookRepository bookRepository){
    //book is never registered 
    if (0==bookDTO.getBookID()){
       Book book = new Book(bookRepository.generateNextBookNumber(),bookDTO.getName());
    }else{
       //book is been registed so we get it from Repository
       book = bookRepository.findById(bookDTO.getBookID()); 
    }
    book.setAuthor(bookDTO.getAuthor);
    ...
    return book;
}

option 2

the BookManagedFacade has a registerBook function:
public registerBook(bookDTO){
   Book book = new Book(bookRepository.generateNextBookNumber(),bookDTO.getName());
   book = BookDTOAssembler.fromDTO(book DTO,book);
}

//add another function in BookDTOAssembler.fromDTO 
public static BookEntiy fromDTO(BookDTO bookDTO,Book book){
    book.setAuthor(bookDTO.getAuthor);
    ...
    return book;
}

With one is better? Or It can be implemented in a better way..?

jgauffin
  • 99,844
  • 45
  • 235
  • 372
tobato
  • 65
  • 1
  • 1
  • 3
  • 1
    Frankly, I would stay away from Dozer. We're using it in my current project, and I hate it: it forces you to do some things manually, or to completely break the encapsulation of your objects by adding setters that shouldn't be there. And some operations must be done without it anyway. And the biggest problem: if you happen to rename a property, everything will compile fine, but will produce incorrect results only at runtime. Transforming DTOs into entities and vice-versa is tedious, bt it's simple. Doing it manually makes sure encapsulation is preserved, and allows refactoring. – JB Nizet Dec 16 '12 at 09:02
  • It's true! If anything change,it can be found at runtime! What is your advice about my question 2? – tobato Dec 16 '12 at 13:00
  • I prefer having a method that just copies from a BookDTO to a Book, and doesn't care where the Book comes from. – JB Nizet Dec 16 '12 at 13:09
  • 1
    you prefer fromDTO(BookDTO bookDTO,Book book) ? – tobato Dec 18 '12 at 01:53
  • About runtime errors - you can write tests for conversion between entities/dto. – Cherry Jul 06 '16 at 11:10

1 Answers1

7

Typically you do not transfer objects (DTO representations of the domain entities) back to the server. Because if you do so you break encapsulation since anyone could just apply changes to the DTOs and then send the information back.

Instead you should create a service interface which is used to modify the objects since it allows the server to apply changes to it's model.

So the service is really splitted up into two parts:

  1. A query part which is used to fetch DTO representations of all entities
  2. A command part which is used to apply changes to the entities
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • 1
    Nice answer. I agree. However, I think that what you send back to the server is still a DTO. The difference is that you don't map a DTO back to a domain entity. Instead, as you state, the DTO represents the command you wish to apply to an existing entity. For commands that create new entities, the DTO would provide the data required to create said entity. – eulerfx Dec 18 '12 at 19:53
  • yeah. I'm just saying that you should not send a DTO representing all information in the domain entity back. – jgauffin Dec 18 '12 at 20:17
  • 1
    yes,i know you talk about cqrs..But at this time ,we don't have a cqrs implement..So..if i have a lots of propertys in book,how to pass these propertys into a service interface? Or should I provide interface like 'updateName(),updateAuthor()..updatexxx' and the client call this interface one by one ? – tobato Jan 08 '13 at 04:27