Let's consider some master-detail form representing a customer order:
So, there are two entities connected to each other with an 1..* association. The master entity contains an association accessor returning a row set of detail entities:
That's it!
So, there are two entities connected to each other with an 1..* association. The master entity contains an association accessor returning a row set of detail entities:
public RowIterator getCustomorderitem() { return (RowIterator) getAttributeInternal(CUSTOMORDERITEM); }And, for example, we need to run through the detail rows before posting master entity to the database and do some job:
protected void prepareForDML(int operation, TransactionEvent e) { super.prepareForDML(operation, e); RowIterator ri = getCustomorderitem(); while (ri.hasNext()) { CustomorderitemImpl item = (CustomorderitemImpl) ri.next(); //do some job ... } }In order to prepare and return the row iterator with detail entity rows the framework creates some internal view object, attaches it to the association and queries the database for the required rows. If the "association consistency" mode is on, the framework applies modified rows to the rows fetched from the database. So, if we do any modifications with order items in our form, the framework takes care of these modifications and includes them to the row iterator. And everything seems to be ok, but the framework executes the database query each time whenever we ask for the association accessor. The question is - do we really need that? Do we really need to ask the database for the rows that we already have in memory and represent in UI? In most cases we don't . In order to prevent these unneeded queries we can change the query mode of the internal VO to be executed in memory:
public RowIterator getCustomorderitem() { RowSet rs = (RowSet) getAttributeInternal(CUSTOMORDERITEM); rs.getViewObject().setQueryMode(ViewObject.QUERY_MODE_SCAN_ENTITY_ROWS); return rs; }
That's it!