Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Many-To-Many Relationships

Former Member
0 Kudos

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:

  • Modeling both business objects separately
  • Modeling one “association class” business object to store the associations between those business objects
  • Create an OData service, having two entities representing exactly the business objects
  • Implement the getEntitySet of both entities: For expand use the “association class” business object to find all related business objects of the other entity

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

1 ACCEPTED SOLUTION

former_member182889
Active Participant
0 Kudos

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

8 REPLIES 8

former_member182889
Active Participant
0 Kudos

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

0 Kudos

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):

  • create two business objects: Orders, Products
  • create a sub node for "Order Items" in Order BO
  • create a business object representation node for Products as sub node of the order item
  • ...

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

0 Kudos

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

0 Kudos

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

0 Kudos

Hi Svenja,

honestly, I do not have experience on that, but what I know is:

  • "redefine" creates a service based on a business object ("inside out"), the MPC and DPC being provided by GBI. Thus, I guess you are limited with respect to your entities and associations to what GBI expects to be relevant. It might be, that Cross-BO-associations are not in scope for GBI.
  • SADL is based on an outside-in approach: You model your entities and their relations and lateron bind them to the BO model. This should give you much more flexibility. Technically, I don't see any reason why a Cross-BO-association should not be followed...

Cheers,

Oliver

0 Kudos

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

0 Kudos

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

0 Kudos

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