ORM objects and system layering
When you get an object out of an database with an ORM you typically get back an object with a layer of ORM semantics attached. Some examples:
- If you access a property of the object is that going to generate a database request?
- If the object is mutable (a common default in ORMs) then what happens if that object is mutated?
- How is identity and equality handled? Can you have two instances of the class with the same identifying fields? If so, if you change one, what happens to the other?
The specifics differ between language and ORM but the nature of the concept means that there basically is always some additional semantics.
For small projects I don't think this matters. For larger systems I have found it raises complex and subtle questions about subsystem boundaries and layering.
For example, If you pass an object through to the view layer, that view should be free to do whatever it wants without concern that it is e.g. going incur database access overhead.
If the ORM objects are mapped to non ORM objects to mitigate the issues that arise, what value to we have in mapping into these special objects to start with? Which layer of the system owns the mapping? Is this mapping producing a potential parallel class hierarchy?
It seems to me that trading clear boundaries, and obvious (if tedious) code for blurry boundaries and magic code, in one of the most straight forward portions of our code bases is a net loss. I sometimes wonder if we as developers get suckered into making things more complicated in our data access code simply to make it more interesting.