6

I have 2 entities - movie and actor - that have M:N relationship. When designing DTO objects for these entities I am not sure what's the correct way to go.

Movie

@Entity
@Table(name = "Movies")
public class Movie extends AbstractBusinessObject {    

    private String name;
    private String short_info;    

    @ManyToMany
    private Map<String, Actor> cast;

}

Actor

@Entity
@Table(name = "Actors")
public class Actor extends Person{

    private String name;

    @ManyToMany(mappedBy = "cast")
    private Set<Movie> movies;

}

Now concerning the DTOs: I've come across two different ways how to deal with 1:N and M:N relationships.

Saving only IDs:

public class MovieDto {    

    private String name;
    private String short_info;    

    // Long represents Actor's ID
    private Map<String, Long> cast;

}

However as said here I thought that Instead of performing many remote calls on EJBs, the idea was to encapsulate data in a value object, and this approach clearly breaks the rule.

Saving DTOs in DTOs: Another approach would be to store Actor's Dto, instead of its ID.

public class MovieDto {    

    private String name;
    private String short_info;

    private Map<String, ActorDto> cast;

}

It seems to me that this approach would be faster, as I don't have to call the database everytime I need to show actor's name for example.

Is this assumption correct, or would it be better to store only IDs (even considering the space consumption of the second approach)?

Plus the second approach would result in a number of DTOs for one Entity. For instance, I don't need to know what movies has actor played in when looking at a "movie page", but I need to it when looking at an "actor page".

Community
  • 1
  • 1
Kuba Spatny
  • 26,618
  • 9
  • 40
  • 63
  • Do you really need dtos? They are often just duplicate code. You could return an entity, which only has the id field set – Sami Korhonen Nov 04 '13 at 18:17
  • Even though its duplicate code (initially), it simplifies a lot as the project grows big. Simple example is Front-end depends on the UI designers who don't really care if an entity/domain model has the information they are trying to present. So its backends job to aggregate the info and pass to the frontend through DTO's. – Ayyappa Feb 24 '20 at 12:44

1 Answers1

4

It is perfectly acceptable to embed other DTO instances inside a parent DTO. Of course, this can get prohibitive if the object ends up being extremely large. So this is where you have to make some kind of tradeoff.

One way to get around this is to have a partial representation and a full representation. In cases where you don't need the complete data, you can use the partial representation. In cases where you do need the full data, you can use the full representation. You can even have it so that the full representation embeds the partial representation inside it (composition) and simply defers calls to that (for the partial data).

Another approach I have used before is to tell my mapper (that converts the entity to the DTO) if I need the full data. This way the mapper can decide if the DTO needs to be populated with additional data.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • 1
    In this example, aren't there endless cycles if you make a DTO that contains other DTOs? Create a MovieDTO, which has ActorDTOs, each of which has MovieDTOs, each of which has ActorDTOs, etc etc...how do you create DTOs when Entities reference each other? – user798719 Nov 28 '13 at 02:15
  • @vivin-paliath : Considering here we pass an embedded DTO, can you share an example on ideal way to pull data from multiple repositories/DAO's and map to a single DTO? Until now, I have seen examples of data mappers taking single Repostiory/Entity alone. Not sure how to handle if we have a scenario where one DTO needs to be constructed from multiple Entities. Is it fair to have the repositories global so that we can pull them when ever required in our mappers? – Ayyappa Feb 24 '20 at 12:48
  • @Ayyappa I would ask a separate question about that. – Vivin Paliath Mar 03 '20 at 19:56
  • @VivinPaliath : It would be great if you can answer this - https://stackoverflow.com/questions/60439844/how-entities-covered-with-in-an-aggregate-root-are-saved-in-ddd – Ayyappa Mar 03 '20 at 20:15
  • @VivinPaliath Did you have a look? – Ayyappa Mar 19 '20 at 09:31