BDO to DAO

In the previous blog post I gave my opinion about whether or not restrictions should be applied on the BDO (business domain object), the DAO (data access object) or both. The conclusion there was that it makes the most sense to put the restrictions and checks for them on the object that actually caused the restriction, and only on that object. This however again makes it a bit odd that we have different objects in the first place, so why bother?

While you can definitely go without BDOs, as I have seen many projects like that, with only DAOs and DTOs. The question then becomes, where do you put all of the logic? Since both the DAO and DTO are simple objects with pure getters and setters. Their only purpose is to store and transfer data, putting logic there doesn't seem to make much sense. Not only doesn't it make much sense, but it can be dangerous as well. Libraries likes Jackson rely on getters and setters to determine how to (de)serialize an object. This means that adding methods to an object can cause this object to have more fields than you desired.

Moreover, DAOs and DTOs typically consist of basic fields as they need to be stored, while application logic may require more complex data structures. It is also a bad idea to have temporary state in these objects as this makes the object unpredictable to work with, as you may assume that the field gets loaded from the database. This all are good points to consider introducing a BDO to encapsulate your business logic. I have however had issues with mapping between DAOs and BDOs and vice versa.

The problem lies in how do you create the objects? Since a BDO is an important object and should be able to guarantee it's state, you don't want to have a lot of setters to manipulate the object, instead you should have precise and specific methods. This however makes initializing the object from a DAO more difficult. You can't have your BDO depend on your DAO and thus having a constructor where you pass the DAO as a parameter is a big no as well. The only solution I have found for this is to use the builder pattern. This way the BDO can still guarantee it gets constructed in a correct state (by adding validation in the constructor) and you have all the freedom you need in the mapper. Once the BDO is constructor, only the specific methods can be used to manipulate the object and no (unless needed) generic setters are present.

The other way around turns out to be problematic as well, how do you convert a BDO to a DAO? There are actually two different cases, one is where you create a new object and thus a new DAO. Another case is where you update an existing object and thus need to have a DAO with the correct id (or even the exact same object). Since a DAO is simply a data object, there is nothing wrong with having setters for those fields that can actually be modified. One field that should never have a setter however is the id of the object. This should be generated by your database (or other storage system) and should not be modifiable or bad things will happen. Due to the lack of a setter (and potentially some other fields), you can't just create a new instance of the DAO for an existing object as you won't be able to set the correct value for the id. The solution? You need to have a method that can update an existing DAO with all the fields that can be set. This method can be re-used for creating the object as well, where after creating the object with all the fields that can't be changed, you pass this object and populate it further.

Another side-effect of this strict DAO limitation is that testing becomes more difficult. Since it is impossible to create a DAO with an id yourself, I had to fall back to creating mocks for my DAOs. This is not perfect, but it isn't that much of a hassle either, since a DAO shouldn't have any logic and only have some setters.

There is much more to be said about the split between DAO/DTO and BDO and my following blog post will go a bit more about specific logic for DAO and DTOs, and why it may be tempting to have logic in them.