Short: I want to provide an API to the client that is DB efficient. That is, I want to give the client just the information it needs, no more, no less, and do it in one method call.
Long: Say I have an HR application. So there are a lot of model objects "floating" around. There are Employee, Address, Payroll, Boss, Department etc. All relating to an employee. Now, I have some client that wants to get some of the employee's related details. Say it is for drawing a web page. I can have something like this
EmployeeAssemply EmployeesService.getAllEmployeeData(int id)
This will return all data for an employee. The problem here is that it may return data that the client is not interested in, thus doing a lot of unnecessary work.
I can do this
Employee EmployeesService.getEmployee(int id)
Address EmployeesService.getAddress(int id)
But this has a drawback that it means several queries into the DB to retrieve each piece of information.
So, my question, is how to give an API where the client can specify what data it wants. The problematic part is dealing with relations. For example, a Boss may have several Employees, how can the client tell, when requesting data for a Boss, what data of the Employees it wants (e.g., it wants only the Employee and Adress data for each of the Boss's employees).
It is idealistic to provide "only" the data that the client wants. And if it's an API you are developing, then it's an educated guess, if not a hypothesis that the caller would want only a certain number of attributes.
Having said that, if you analyze the attributes of your model objects, you can categorize them into three types
- minimal, least common set of attributes that a caller may need, such as name, ID, type, etc.,
- standard, minimal attributes plus other attributes of that objects, but not the relationships (or the attributes of the related objects)
- extended, standard attributes plus the relationships and attributes of related objects.
These attributes/association requirements can then be passed to your remote calls using what I call a Selector. You probably may want to have two flavours of your API - those that accept Selectors, and those that do not (which means, they use the minimal selector).
This Selector can then also be used to specify special attributes or associations that your callers may want, filtering and/or sorting criteria. For example, in your call "getAllEmployeeDetails" :
Selector theSelector = SelectorFactory.getSelector(SelectorConstants.STANDARD);
The above call will return all standard attributes of the employees with the departments information as well, sorted first by name and then by salary
thanx for your response.
This method however, is not (as i see it) what i'm looking for.
Continuing my example, say I have several pages in which I show the Employee data. Then each of them uses a different set of objects relating to the Employee, some of them may need only the minimal or standard set, but others may need objects from the extended set, but only some of them.
Well, I'm not sure if I understand your reservations, but the whole point of such an implementation is that your clients will have to specify what basic information they want, AND any additional information they require. Clients that have minimal info will use the default set of data returned.
In the JSP example you mentioned, I guess what you are trying to say is that the "extended" set may contain too much info. As mentioned before, it is upto you to define the amount of info each "set" contains.
For a particularly complex model, you could have several subsets.
Would using lazy-loading not help you out here? By default, you would load your "parent" entity (e.g. Boss) but the "child" entities (e.g. Employees) are only loaded when the client calls a getter method (e.g. "boss.getEmployees()"). That way your child data is loaded on-demand, rather than all at once.
The client could also supply a "hint" to the "parent" entity (e.g. a boolean parameter), indicating whether it should load the child entities by default or not. This could allow a more efficient query to be made, for clients that know in advance they will need all the data.
lazy loading won't help since the client is not inside the server's transaction, so the entity beans (i'm guessing that's what you're referring) cannot work (reliably) there (that is, they may return inconsistent data for each property)