I have been thinking about a design problem and possible solutions in my own. I am pretty sure I am not the first one to have noticed it, but I cannot google for it since I do not know the standard naming of the different participants.
It is NOT the state pattern.
My problem is that, when dealing with ORM, I often end with something like that
Employee -------- Id Name Surname BirthDate DefunctionDate
And using an Object Relation-Mapping (in my case JPA), I end with two entities,
Now, most of the fields of
Employee are just "intranscendent"(*1). It really does not affect the application if the Employee's name changes from 'John' to 'Mike'. As long as I put some validation for the input fields. But if, say,
defunctionDate changes from
null to some date, some logic must be executed (for instance, closing the current contracts, revoking system access, etc.). I would call those terms "transcendent"(*1).
The first step would be add an specific operation which sets such field
setDefunctionDate and handles such logic, and I am ok with that. The problem that appears is how to ensure that the fields are not updated when updating "cargo" data.
I see three "easy" options:
Ignore changes in a bean: If I have an
update(Employee employee)method, then each time the method is executed I should retrieve the object from DB and set the "transcendent" field(
defunctionDate) of the incoming object with the value from the object stored in the DB. That "retrieve the object from DB" means one or several extra accesses to DB, which are not a good thing. Also, this has issues when there is cascading of the changes.
"Observer" pattern: Like 1., but in this case a modification is found in a "trascendental" change a listener that handles the extra logic is fired.
Another possible solution is having a method for each field in the entity, but I think this will usually be too verbose, and will break the purpose of having an ORM.
Of the previous options, I thing 2) would be the best, but I still do not like the fact of the extra DB accesses even when no trascendent field has been changed.
The only solution I can think of would be moving those "trascendental" fields to a separate entity, which would be in a one-to-one relationship with the original entity. Something like
Employee -------- Id Employee_Trascendent Name --------> --------- Surname Employee_Id BirthDate DefunctionDate
The API would only allow direct modification of the
Employee entity, and
DefunctionDate would only be modified by an specific API method.
That said, I find my solution a bit overcomplicated and, since I cannot see any reference to anything similar, I think that maybe I am missing some more obvious solution.
I would like your help to determine the correct terms to search ideas for and, if why I propose has a name, its name.
*1: If you know a better term please tell me it, remember I do not know the proper terminology.