Auto-committed objects are objects that have not explicitly been committed to the database themselves, but are referred by other objects that have been committed to the database.
Say you have a typical domain model with a Customer entity and an Order entity where there is a reference from Order to Customer (so a Customer can have multiple Orders). Performing the following activities in a microflow will lead to an auto-committed Customer object:
(Note: steps 2-4 could be implemented using a single 'Create' action that also sets the reference and commits the object.)
Now, when committing the Order object to the database, the Runtime also wants to commit the reference to the Customer object, as that data is a part of the Order object. But because the Customer object has not been committed yet, storing its ID as a value in the database would lead to a "corrupt" database. The Customer's ID would be stored, but there would be no Customer record with that ID.
To mitigate this problem, the Customer object is automatically committed to the database when such a situation occurs. However, this commit is done without validations and without executing events, so the Customer object might not be valid yet. Hence the status 'auto-committed'.
We expect auto-committed objects to be committed later on. This could even be in the same microflow, but it could also be after the user completes the current action (e.g. pressing the 'Save' button in a page when adding a new customer with a new order). When the auto-committed object is not committed later on, this is basically a bug in your application. Hence the warning messages that you see in the Runtime log.
When the user that created the auto-committed object signs out, the auto-committed objects for that user are deleted (if any) and a warning is logged if such objects existed. Any references from committed objects to auto-committed objects are cleared, so that the database remains in a consistent state. So in the example above, when the user signs out the Customer object is deleted and the reference from the Order object to the Customer object is cleared.
So to solve the problem (and the warnings) you need to examine your model and see if you can think of ways that the Order can be committed while the Customer is not. If you make sure that cannot happen anymore, the auto-committed objects should disappear as well.
Hi Benny, Bas,
Our log contains thousands of auto committed clean up warnings. This
" When the auto-committed object is not committed later on, this is basically a bug in your application. "
Is not completely true. Because users can navigate away, hit a menu item, click the browser back button and so on. There is absolutely no way you can prevent users from doing is and so creating auto committed objects that will never be committed.
Also there are some side problems. In your example imagine that committing the order will update the stock of the product connected to the order. This happens in the before commit. Also the order has a before/after delete event that updates the stock of the product again when the orders gets removed.
Let's assume that there is delete behavior between the customer and order. The auto-committed customer will be removed by session destroy. It also deletes the order (auto-committed object clean up respecting delete behavior works from Mendix 5.6.0). But auto-committed removal doesn't execute the BDE event of order. So now your stock volume of the product is corrupt.
Situations like these happens al the times, and instead of preventing data corruption, auto committed object is for one of our applications (an application for non professional users (who often navigate away assuming that everything is saved)) a main cause of data corruption.
To prevent this kind of corruption I can only think of the following possibilities:
Any other ideas? This is really a serious problem of which I'm sure occurs in many applications, but probably not everybody is aware of it..
About the three possibilities Herbert mentioned: 1. Simulate the old Mendix behavior: I tried that to implement, it's possible to a certain extent, but not 100% safe, so in the end I didn't choose for this option. 2. Directly commit created objects: I NEVER do that; ONLY when the user explicitly activate the save button I want to commit such objects to prevent issues like you mentioned. So only at that point I fire change-events, or in your example update the stock of the product and so on. The downside sometimes is some redesigning of the workflow, but still I think the best way to handle this, as long as there are no better options at hand. 3. Before session removal retrieve the auto committed objects: in my case that's not necessary