11-27-2014 1:56 PM
Hi all,
We have a scenario where many-to-many relationships between business objects are required. We’d like to use the goodies of BOPF, since our requirements include, e.g., web services to read and update business objects (using OData).
Right now we are struggling to model such an n:m relationship. I know, that, on the one hand, business objects are hierarchically structured and therefore only support 1:n relationships. On the other hand, OData supports n:n relationships: Both …/Orders?$expand= Products and …/Products?$expand= Orders are possible if implemented correctly.
Is there a way to model an n:m relationship using business objects/BOPF, so that one OData service offering both associations can be generated automatically?
The only possibility we see right now includes:
This looks like an unnecessary effort since all this could be generated, right?
In comparison, JPA has a @manyToMany-association, which automatically creates the association class and table. Is something similar possible using business objects/BOPF?
Thanks,
Svenja
12-01-2014 7:48 AM
Dear Svenja,
As you already said, there are no n:m Associations in BOPF. Every association is directional with source cardinality one. Nevertheless, it is possible to picture e. g. the relation between products and orders – with two different associations, but with cardinality unbound.
I was thinking about this a little longer now and believe, that this is actually true for all n:m relations: I’d even say that there are no real n:m associations, but only n:m relationships. For me (and technically for BOPF), an association is always owned by an entity. This is also expressed by the fact that association changes are propagated via the service manager for one entity. However, at runtime, a link-table which is the runtime-representation of an association can have multiple source instances pointing to multiple target instances and vice versa. This is due to the fact that the association can be resolved for multiple source instances, each of the being of unbound cardinality – but not restricted to point to different target entities.
Thus, I do not see any reason why not to model two associations.This would mean to have one service with two entities with two (directional) associations.
Coming back to your sample, the association between products and orders is actually at item-level: One order item can relate to one product. One product can occur In multiple order items.
The relation between Order and Product is actually a “shortcut” for /Orders/$expand=items/$expand=products (if one can note this in OData like that, I’m not there yet ). The relation from Products to Orders is also a shortcut for /Products/$expand=orderItems/$expand=toParent - at least in my mind. All of these associations could be modeled (based on (reverse-) foreign-key-mappings). The shortcuts could be realized with implemented associations which relate orders and products directly (internally following the items-association). However, I’d discourage from doing so as implemented associations cannot be pushed down to the database (as joins).
Is there any reason why not to implement your requirement like this?
Cheers,
Oliver
12-01-2014 7:48 AM
Dear Svenja,
As you already said, there are no n:m Associations in BOPF. Every association is directional with source cardinality one. Nevertheless, it is possible to picture e. g. the relation between products and orders – with two different associations, but with cardinality unbound.
I was thinking about this a little longer now and believe, that this is actually true for all n:m relations: I’d even say that there are no real n:m associations, but only n:m relationships. For me (and technically for BOPF), an association is always owned by an entity. This is also expressed by the fact that association changes are propagated via the service manager for one entity. However, at runtime, a link-table which is the runtime-representation of an association can have multiple source instances pointing to multiple target instances and vice versa. This is due to the fact that the association can be resolved for multiple source instances, each of the being of unbound cardinality – but not restricted to point to different target entities.
Thus, I do not see any reason why not to model two associations.This would mean to have one service with two entities with two (directional) associations.
Coming back to your sample, the association between products and orders is actually at item-level: One order item can relate to one product. One product can occur In multiple order items.
The relation between Order and Product is actually a “shortcut” for /Orders/$expand=items/$expand=products (if one can note this in OData like that, I’m not there yet ). The relation from Products to Orders is also a shortcut for /Products/$expand=orderItems/$expand=toParent - at least in my mind. All of these associations could be modeled (based on (reverse-) foreign-key-mappings). The shortcuts could be realized with implemented associations which relate orders and products directly (internally following the items-association). However, I’d discourage from doing so as implemented associations cannot be pushed down to the database (as joins).
Is there any reason why not to implement your requirement like this?
Cheers,
Oliver
12-01-2014 11:06 AM
Hi Oliver,
thanks for your idea. Theoretically speaking, I agree with you
You advise to do the following (I hope I'm getting what you mean - if not, please correct me):
If I now generate an OData service based on the Orders business object, I do not see an entity for the Products business object (which means, I cannot navigate to it). Only the Order Item entity as a 'normal' sub node is showing up as an entity. Am I doing something wrong?
You can try it with the demo BO: /BOBF/DEMO_SALES_ORDER
Using OData, I can only use one BOPF service as source for the data model, so I cannot include the Product BO as well.
Thanks,
Svenja
12-01-2014 11:50 AM
Hi Svenja,
theoretically, we seem to agree. However, I do not have any practical exposure to OData on BOPF yet. But to me it seems a tooling limitation. Are you refining the BO-Service with GBI or are you modeling a GW Service and bind it via SADL?
Cheers,
Oliver
12-01-2014 12:11 PM
Hi Oliver,
I tried it using the refine approach in SEGW, because everything is generated automatically. Maybe it works with SADL, because it is more flexible (although it requires more effort)?
Thanks,
Svenja
12-01-2014 12:51 PM
Hi Svenja,
honestly, I do not have experience on that, but what I know is:
Cheers,
Oliver
04-02-2015 10:10 AM
Hi Oliver,
it took a while, but we finally understood how to implement this (btw: the BOPF training was very helpful for this :-))
We created a link table and own associations between the link table and both nodes. Then, additional associations can be implemented for navigation between the nodes directly, internally using the link table. The direct associations can also be used in the OData Model using SADL binding. Hooray!
Thanks again for pushing us in the right direction!
Svenja
04-02-2015 11:11 AM
Dear Svenja,
That's great to hear, thanks for informing.
If I got you right you now implemented an association (using the /bobf/if_frw_association interface), right?
This is of course possible. However, I want to point out that this is an implementation in ABAP and thus cannot be executed by other runtimes. If you aim for the very to have the association resolved on the DB (using joins), the implemented association cannot be used.
In this case, it might be more appropriate to follow the composition to the link table (which is modeled) and the foreign-key-based cross-bo-association from there on.
It may even be the case, that SADL supports something like this hopping of associations - but I'm not sure on that.
Cheers,
Oliver
04-13-2015 9:31 AM
Hi Oliver,
yes, we implemented this using the /bobf/if_frw_association interface.
Since we are not dealing with huge amounts of data in our tables, the performance of the ABAP implementation and executing two database selects instead of a join should not be a problem. Or did you mean something else?
Kind regards,
Svenja