Should DTOs in a composite DTO reference each other by primary key or by object reference?

4.2k views Asked by At

There is a recommendation that transfer objects should not contain object references to other transfer objects. Instead, they should use the primary keys of the other transfer objects as foreign key fields.

Simple example with Order and Customer as entities

Clearly, an OrderListDTO containing a list of orders without customer details will contain foreign keys to the details of the ordering customers.

A composite DTO OrderWithCustomerDTO will have object references to an OrderDTO and to a CustomerDTO. But should the embedded OrderDTO itself have a object reference to its CustomerDTO in this case? Or should it use the primary key of the ordering customer?

Indication for object references

One advantage is that the client can directly use the transfer object, e.g. as presentation model. I tend to accept this approach for transfer objects that are always completely self-contained, e.g. a composite DTO with related DTOs or a complete tree. The client can rely on the self-containment. The client doesn’t need to post-process the transfer object at all.

Indication of primary keys as foreign keys

The advantage is that internal and external references are treated the same way. I tend to require this approach for transfer objects that might contain external references, e.g. a subtree with external childIds. The client must iterate over the complete list to resolve the external childIds.

More complex example with a tree or subtree

The transfer object in question now is a tree or subtree. Technically, it's a list of nodes.

Is it ok if the nodes in the transfer object reference each other by object references like the NodeTOWithObjectReferences below?

public class NodeTOWithObjectReferences implements Serializable {
    private long id;
    private NodeTOWithObjectReferences parent;
    private List<NodeTOWithObjectReferences> children;
}

Or must the transfer object replace EVERY object reference by a foreign key field like the NodesTOWithForeignKeys below?

public class NodesTOWithForeignKeys implements Serializable {
    private List<NodeDetail> children;
}

public class NodeDetail implements Serializable {
    private long id;
    private long parentId;
    private List<Long> childIds;
}


(I opted for transfer objects to encapsulate the domain model from the clients and to provide client specific data views.)

1

There are 1 answers

1
Roman On

As a general recommendation, transfer objects should not contain object references to other objects. Instead, they should use the primary keys of the other objects as foreign key fields.

Could you attach a link to the source of this recommendation? It's at least not obvious to me.

In my current project I use transfer objects which contain object references. It's convenient and I haven't met any problems with this approach yet.