| Project: | iMo-2009D |
| Component: | Server code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | mvbergeijk |
| Status: | closed |
Method model:StoreData() calls the business entity for storing data and passes it's DataContext by means of dataset-handle dsContext.
The DataAccess object saves the data and calls DataAccess:CascadeDelete() for deleting child records. CascadeDelete() invokes AttachDataSource() for fetching child records. AttachDataSource() uses parameters, query-names, filters and other options from the DataContext.
This DataContext object is the same as the one used by the model for fetching data.
In our error scenario we set an option in the DataContext to inform the business entity we only want to fetch the top-level buffers. Normally this is not a problem because we don't use DataContext options to control the way a business entity is saved. It happens to be problem when CascadeDelete() is invoked. This method invokes AttachDataSource() which uses this option and because of this option it doesn't fetch the child records.
Question is what is the real error.
- DataAccess:SaveData must clear the DataContext before storing?
- Must the model use separate DataContexts for fetching and storing?
- Is it the reponsibility of the model to clear the DataContext before storing data?
- Must CascadeDelete() clear the DataContext?
- Must the AttachDataSource() method not read the option when being invoked from CascadeDelete?
DO WE NEED A DATACONTEXT FOR SAVING DATA ANYWAY!
I'm voting for the first one.
Comments
#1
I think CasadeDelete is just a nice trick to maintain the contents of a dataset, nothing more that that. I mean, if you have an order and orderlines in the dataset and you delete the order from the dataset, then the orderlines should also be removed *from the dataset*.
Orderlines probably also need to be removed from the database. And backorder records, if they exist, should also be removed from the database and shipping/packing instruction records too. There can be a lot of stuff in business rules and/or database consistency rules that ought to be maintained.
The dataset structure is probably designed to match the needs of the upper (business) layers, not for the lower technical layers. So the dataset will hardly ever be rich enough that all affected and dependent data is in there.
What I mean to say is: CascadeDelete in the dataset is fun but you should not rely on it for data consistency.
#2
CascadeDelete is a method that helps you to delete a business entity from the database without having to code this for each DataAcces object. So when I delete the order it's ordelines need to be deleted as well. This method is in the DataAccess object for technical reasons (database integrity).
Backorders and shipping/packing instructions are very likely not part of the order but are seperate business entities. Deleting these, when deleting the order, is not a matter of data consistency but a matter of business rules. Business rules need to be implemented in one or more business tasks.
The DataAcess layer is for keeping the database consistent not for implementing business rules.
#3
Yes, I agree that data integrity rules belong in the DA and business logic rules do not belong in the DA.
But the point I was trying to make is that data integrity should not rely on dataset design. There can be more involved in data integrity than what is in the dataset so it is quite normal that CascadeDelete is not sufficient.
#4
While working on a workaround for this issue I came to this proposal to resolve the problem.
Create a new method AttachSaveDataSource() for attaching the datasource to be used for saving data.
This method is called from SaveData(). The default implementation of AttachSaveDataSource() calls the current AttachDataSource() method.
So everything that has been developed so far keeps working. If you made changes to AttachDataSource() which will disturb the save of data you have to override this method and implement the correct datasources.
@Imo.Method.
/* Abstract method to override with code to attach a datasource, identify a callback or set the buffers to NO-FILL */
method protected void AttachDataSource ():
message program-name (1) 'must have an override':U view-as alert-box.
end.
@Imo.Method.
/* Abstract method to override with code to attach a datasource for saving the dataset.
Default it calls AttachDataSource() to use the datasource for fetching data. */
method protected void AttachSaveDataSource ():
AttachDataSource().
end.
@Imo.Method.
/* Save the data from the dataset integero the persistent store
* Entry pointeger for the business entity
* Precondition: attributes dsDataset and dsContext are valid handles to a real dataset */
method public void SaveData ():
AttachSaveDataSource().
...
end method.
#5
Adding the AttachSaveDataSource seems like a good option to overcome the problem. Without going into theoretical discussions :-)
#6
I think that the model (in general the class that calls the StoreData or FetchData) needs to set correctly the dataContext information (by clearing the DataContext before calling SoreData, using another DataContext etc)
#7
#8
So this is fixed I guess?
#9
Fixed in 2010A release
#10
#11
Automatically closed -- issue fixed for two weeks with no activity.