Now that I have understood what a DTO is good for, I’m thinking about ways to improve it. As they are right now, our DTOs are POJOs extended by JSR 303 annotations for defining constraints on their fields/methods. The annotations are duplicates of the annotations defined on the corresponding entities.
Since I have worked with the UI code most of my time so far, I have felt the drawback of not having JavaFX properties in our DTOs: they cannot be observed easily by the GUI controls. There is a wrapping mechanism to add this observability, but it is rather complicated to use and requires a lot of extra code.
So why not make the DTOs full JavaFX beans? After all, we would not be the first project to do this. Two common objections were raised when I brought this up:
- DTOs are created on the server which should not have dependencies to a GUI/client technology.
- We would need to mix JavaFX beans with JSR 303 annotations.
Let’s address the first point. Yes, having a GUI dependency in your server code is not a good idea. But are JavaFX properties a GUI technology? Or even a client technology? It’s a bit unfortunate that they were introduced as part of JavaFX in a
javafx.* package such that everyone identifies them as a GUI technology at first sight. It’s an image problem. I would argue they are a self-contained technology which is independent of any GUI parts of JavaFX and could therefore be used for any data model, no matter if it’s on the client, on the server, or shared between both. Even if one does not use JavaFX for the frontend, depending on JavaFX properties would do almost no harm in practice since JavaFX is part of the JDK and your server code certainly depends on the JDK. So the no client dependencies on the server argument is merely a formal one in my opinion.
What about the second point, mixing JavaFX properties with bean validation annotations? I have never tried it myself, but I have the feeling it cannot be that big of a problem. If it works in the FXForm2 demo, why should there be a fundamental incompatibility between these two technologies? But I admit that a good prototype is needed to make a final judgment.
We will have a meeting on this tomorrow. Let’s see what the others think.
Having worked a lot with EMF and Eclipse RCP applications based on EMF as the framework of choice for transferring domain models into code, I never got in touch with real-life examples of Data Transfer Objects (DTOs). I was familiar with the pattern in theory, but I never saw a DTO in practice since EMF works fine without them, even in a client-server architecture.
This changed recently. My new project is a client-server system which does not use EMF for implementing its domain objects. DTOs are used heavily to transfer data from the server to the client and vice versa. During my first journeys through the unknown code base, I stumbled upon a lot of DTOs and wondered what they were needed for at all since they seemed to introduce a lot of redundancy and required a mapping to and from the entities managed by the server. Wouldn’t it be more efficient and practical to simply use the entities as the shared domain objects on the server and the client? What is right in the EMF world cannot be wrong in the JavaEE world, I thought.
So I did some research and found this blog post by Adam Bien who seemed to confirm my doubts. “JavaEE 7 retired the DTO” was all I needed to hear in order to start a discussion with one of my new colleagues about the whole purpose of DTOs in our project. He was nice enough to take a long break from his current task and give me an extended explanation of why and how DTOs are necessary in our project. He answered all of my questions patiently, even if some of them were perhaps a bit naive and showed my lack of experience with some aspects of JavaEE. Needless to say it was a fruitful discussion.
I did some more research the next day based on his explanation. When I was finished, I had changed my mind. I am now convinced DTOs add value to our project despite the code duplication and the extra efforts for the domain mapping because they embody more than a simple transfer mechanism . Here are the pros and cons of DTOs based on my current understanding:
- Duplicate code (duplicate data models, duplicate constraints,…)
- A mapping to and from the domain objects is required
- DTO exposes the domain model in a form that is tailored for the client’s needs
- Entity should be managed by the server all the time, never deattached from it
- Can save bandwidth by carrying only a selected subset of the entity’s attributes/dependencies
- No client dependency on JPA if entity uses JPA annotations (e.g. for constraints)
- More pros here on Adam Bien’s blog
Resources I found helpful