# DTO, Spring und Hibernate



## DerGrinsemann (6. Juni 2007)

Hallo!

Hat jemand von euch schon einmal ein Projekt mit Spring und Hibernate realisiert und dabei DTO (Data Transfer Object) benutzt (vielleicht mit den Pattern Assembler)?

Ich weiss nicht wo ich ansetzen soll und finde auch keine passenden Tutorials dazu.

Marco


----------



## Thomas Darimont (8. Juni 2007)

Hallo,

ja. Wobei spezielle DTO's eigentlich nur in Ausnahmefällen notwendig sind (u.U. beim Datenaustausch zwischen unterschiedlichen Schichten (Präsentationsschicht, Integrationsschicht / Geschäftslogikschicht) , beim Datenaustausch zwischen zwei (Java) Anwendungen) bzw. in manchen Architekturen komplett vernachlässigt werden können (Beispiel.: kleine JBoss Seam Webanwendung...etc.)

Manchmal bietet es sich auch an die Business Objects direkt zwischen den Schichten hin und her zuschicken je nachdem welche Anforderungen man an das Domain Model hat (Lazy Loading, Datenvolumen etc.)

Das Assembler Pattern verwendet man in der Regel so, dass man ein normales Business Object übergibt und eine spezielle "Sicht" auf dieses Business Object als ein DTO bekommt. Beispielsweise könnte es sein, dass man eine Webanwendung hat wo man in einer Liste verschiedene Daten eines Business Objects anzeigen möchte. Nun sind die 
Daten die man anzeigen möchte aber nicht direkt an dem Business Object enthalten sondern man muss u.U. über mehrere Level Assoziationen traversieren.
( order.getCustomer().getAccount().getId() ). U.U. steht nun in der Präsentationsschicht nicht genügend Kontext zur Verfügung (beispielsweise könnte die entsprechende Hibernate Session an dieser Stelle nicht verfügbar sein...etc.) weshalb die Daten vorbereitet werden müssen. Dazu könnte man nun hingehen und die gewünschten Business Objects (mit allen aAsoziationen) entsprechend komplett voll initailisieren und die dann an die Präsentationsschicht übergeben. Eine andere Variante wäre hier, nur die benötigten Daten aus der Persistenzschicht anzufordern ohne die ganzen Business Objects voll initialisieren zu müssen. Man erzeugt sich also nur eine "View" auf die eigentlichen Business Objects.

Weiterhin werden DTO's auch oft noch mit zusätzlichen "dirty markers" ausgestattet. Wird ein solches DTO zu einem entfernten Client geschickt, dort manipuliert und wieder zu uns zurück gesendet, kann man anhand der dirty markers erkennen, wo, was geändert wurde.

Was sind denn deine konreten Fragen dazu?

Gruß Tom


----------



## DerGrinsemann (8. Juni 2007)

Hallo!

Ich (wir) sind gezwungen DTO's zu benutzen, da sehr unterschiedliche Präsentationsschichten implementiert werden sollen.

Mir geht es einerseits um den Zeitpunkt bzw. Ansiedlung des Transfers. Ich würde es so sehen:


```
Controller <-> DTO <-> Service <-> DAO <-> Domain
```

Wobei im Service der Transfer mittels des Assembler-Pattern erfolgt. Oder?

Schreibe ich für jede Sichtweise eine DTO einen jeweils dafür passenden Assembler?

z.B. PersonSimpleDTO, PersonFullDTO und PersonSimpleAssembler, PersonFullAssembler

Implementiert man den Assembler so?


```
public class PersonSimpleAssembler {

   public PersonSimpleDTO toDTO (PersonDomain personDomain) {
      PersonSimpleDTO personSimpleDTO = new PersonSimpleDTO()
      personSimpleDTO.setFirstName(personDomain.getFirstName());
      ...
      return personSimpleDTO;
   }

   public PersonDomain toDomain (PersonSimpleDTO personSimpleDTO) {
      PersonDomain personDomain = new PersonDomain()
      personDomain.setFirstName(personSimpleDTO.getFirstName());
      ...
      return personDomain;
   }

}
```

Das kommt mir komisch vor, wenn ich diesen Assembler so benutze:


```
public class PersonService {
   public void updatePerson(PersonSimpleDTO personSimpleDTO) {

      PersonSimpleAssembler personSimpleAssembler = new PersonSimpleAssembler ();
      PersonDomain personDomain = personSimpleAssembler.toDomain(personSimpleDTO);

      PersonDomain personDomainDB = this.personDAO.findById(personDomain.getId());
      personDomainDB.setFirstName(personDomain.getFirstName());
      ...

      this.personDAO.update(personDomainDB);
   }
}
```

Marco


----------

