DTO in anger
In this article, I will show you how in JEE architecture using lighweight frameworks, creating a DTO layer is an anti-pattern.
Once upon a time, Sun created standards to interact with the database tier: those where Entity EJB. In their version 2, an EJB entity is a Java class that is mapped to a specific table through the EJB jar deployment descriptor. This class is the true entity Bean. Since EJB calls can be made across different Virtual Machines, through the RMI protocol, no instances of Bean are truly returned.
What is really passed to the client is a reference to another interface instance. This interface must be a subinterface of
javax.ejb.EJBObject or, if running inside the same Virtual Machine, of
javax.ejb.EJBLocalObject. The latter is equivalent to the first, only it removes the checked
RemoteException from all methods signatures.
The following snippet shows an typical direct invocation of an Entity bean:
Context context = new InitialContext(); // Entity bean home interface ClientHome myClientHome = (ClientHome) PortableRemoteObject.narrow(context.lookup("java:comp/env/ejb/ClientSessionBean"), ClientHome.class); // Entity bean local interface Client myClient = myClientHome.findByPrimaryKey(53); // Get accounts of client List myAccounts = myClient.getAccounts()
Now, this client can have accounts. In order to get its accounts list, the client code has to call the
getAccounts() method. But each call to the local interface is potentially remote, creating network overhead.
// This call is no simple method invocation but is made over the network List myAccounts = myClient.getAccounts()
Wouldn’t it be better if I could get all of the needed data, the client and its accounts, in one network call? This is the goal of the DTO pattern. By the way, it is interesting to note that what call Design Pattern in an EJB environment are less so and more a rule to enforce in order to increase performance – end parenthesis.
So, DTO is about creating a C-like structure class (no behaviours, only accessor methods). For a client call, an instance of this DTO is created. Then it is set, eventually by multiple database access in the remote JVM and returned in one network response to the client. The main idea here being: the purpose of the DTO is to minify the amount of network traffic, that’s all.
A good question to be asked is why should local EJB implement this pattern. It could be argued that tomorrow, all calls could be made to a remote server, and that it is good sense to keep this option open.
But in using lightweight persistence frameworks, such as Hibernate or TopLink, there wouldn’t be anymore need for DTO, would it? Astonishingly enough, that’s the second time I come upon a project that still implements this pattern though it doesn’t use EJB Entities as their persistence layer. In the latest occurence, model objects that are loaded through Hibernate are converted into DTO. What are the drawbacks?
- a performance overhead of converting objects from and to the database,
- a cost overhead in the initial configuring of the conversion framework (Dozer in this case),
- a cost overhead in each subsequent modifying of the database structure that should be mirrored in DTO.
What are the advantages of keeping a DTO pattern? The point is, I don’t know (which is a more polite form of ‘None’), but from my point of view, it clearly looks like an anti-pattern.
To go further: