A few years ago, just after I learned about object oriented data types, I also learned about some things that some people hate about using OO to manipulate data for object persistence (storage for future retrieval). Most of the blame is on the OPF.
OPF is slow
We have a system that has a peculiar problem in its last stable version. It has a complex model, one of its business objects has two containers and one of these containers has another three. This means that there are three levels of master-detail (in other words, master-detail-subdetail). Querying 15 to 20 objects is fast to discover these 15 to 20 objects, the problem is putting them in a Grid. When the query is executed, the building of the items, line by line, and the retrieving of referenced objects are perceptible.
This slowness happens because of on demand loading. Objects are not created immediately, but instead their OIDs are stored in memory to be retrieved when necessary. It happens that the retrieval of these objects is done one at a time, generating a lot of traffic with little content, making the database, the network and the system, as a whole, work very hard. Retrieving all the data would be even worse, as this would generate a lot of traffic and unnecessary work for the database.
OPF causes problems in concurrent editing
Persistence frameworks generally keep in memory information about an object’s state when it was read, this way the framework knows if the object was or wasn’t altered in another session. This is a problem in cases when its necessary to avoid conflict, such as updating a quantity in stock. Worse would be to allow the framework to save an object without worrying about concurrent editing, like in the following example:
- User 1 reads object
- User 2 reads the same object
- User 1 increments the stock with 2 units (from 5 to 7)
- User 2 increments the stock with 1 unit (from 5 to 6)
- User 1 saves the object
- User 2 saves the object
The problem: the stock is 6 instead of 8.
OPF requires reading a complete object to execute a small change
A batch price change. All products of a certain category will get a price increase of X %. Its necessary to read all the objects, apply the change and save the objects back, and this is much slower than executing a query directly to the database.
But every problem has a solution
The slowness of the OPF is due to the fact that the objects are read at a snail’s pace. We can use a bulk retrieve strategy that allows the retrieval of a list of OIDs in a few queries. Generally there should be a single query for each class, if this OID list references objects from only one class, one query will retrieve all the objects at once. Just configure this retrieval so that, when reading the first OID that is not in the cache, it also reads the next 30, 50, 100 along with it.
Concurrent editing is usually done when updating a value. Example, increase or decrease a specific field with a certain amount. This is possible by adding a function in the data type that does this type of update, example:
The OPF recognizes this type of editing and instead of doing an update with the result, it will update by incrementing the field with “Qty”.
Batch changes can be executed directly against the database, provided that you take care to maintain the integrity of the database for the OPF. Its not a difficult job, it only requires some attention.
Lastly, I do recognize that there are still problems that are difficult to solve for OO world with regards to object persistence:
- the learning curve is steeper, its only viable with the programmer’s dedication
- the framework needs to be robust, scalable, productive and in constant development, which is not a problem anymore after the birth of PressObjects SDK