The ‘rule’ when to use retrieve over association or retrieve from database is very simple: “Always retrieve from database unless you need the dirty state”. You can see the state transition diagram of an object in the picture here. In practice, this ‘rule’ means that you only retrieve over association when you are working with non-persistent objects, or when you expect a user to have changed an object and you want to use the new values.
Performance is no consideration here: retrieving over association shows intent to use the dirty, unvalidated state of an object and should result in a functionally different outcome than retrieve from database.
[Rant]In general, it seems Mendix Business Engineers have very little understanding of the concepts of clean state and dirty state. I see this with some of my own colleagues, as well as with Business Engineers at customers I visit: like Ronald, they cite performance reasons to retrieve over association. Even worse: Mendix encourages this incorrect modelling in two ways: retrieve over association is the default setting (which it should not be) and if there is no dirty state of an object, Mendix retrieves the object from the database anyway, so that your application functions the way you would naively expect it would function (and this makes the performance argument invalid: “retrieve over association and if not present retrieve from database” cannot be faster than a “retrieve from database”). Eventually, this incorrect modelling may introduce security vulnerabilities into an application, since data in a dirty state must be validated before processing, but this valdation is often skipped.[/rant]
When you do a retrieve over association you do not need to make a call to the database because you already have the object and it’s associated objects. A retrieve from database wil retrieve that object from the database (again). Retrieving from database will give you the state of that object as it currently is stored in the database. So depending on what you want to do you need to decide what is best. Over association is always the fasted way to retrieve an object.
I think, there are three different concepts here that should not be mixed up:
- Dirty state: object containing all changes to the object. Changes can be made by the current microflow as well as by previous accessed microflows and pages
- Validation: Before processing (commit or delete), the changes of the dirty state should be checked by business rules. And when not compliant to the rules the dirty state object must be rollbacked.
- Retrieve performance: the speed with which objects are retrieved. In theory should retrieve from memory be faster, but in practice it’s hardly an issue
In my opinion retrieve by association should be the default action because this allows a developer to make changes to objects by using several microflows and pages in succession before commiting the object (like in a wizard). Retrieve from database is only needed in those cases that you retrieves an object for the first time or if you want to compare the dirty state object with the original object (like checking if an attribute is allowed to change). But yes, you must comply to business rules before commiting...
Mendix says: “Use the retrieve over association if possible. This uses caching, it is more readable, and it uses an index. If business logic requires the database value (because the value over association might be changed), then of course a database retrieve is needed.”
Rom provided a good rule of thumb on when to retrieve by association or from DB.
Retrieve options (association/DB) are just tools for a developer. Having preference for one one over another does not work well in all cases. Personally, I would not use, for example performance property of the retrieve options, as main criteria of choice. For me the main criteria is business requirement (business can very well be a technical domain, say like integration with an external API).