Navigating the BOPF: Part 2 – Business Object Overview
In my previous blog post, I briefly introduced the BOPF framework and its positioning within the ABAP development landscape. With that information in tow, we’re now ready to begin peeling back the layers of the BOPF and seeing how all the pieces fit together from a technical perspective. In this blog post, we’ll get things started by taking a look at the design time aspects of business objects.
Business Objects Overview
According to SAP’s BOPF Enhancement Workbench documentation, business objects within the BOPF are “a representation of a type of uniquely identifiable business entity described by a structural model and an internal process model.” This is to say that BOPF business objects:
- Have a well-defined component model.
- Have a well-defined process model which governs the business object lifecycle, behaviors, etc.
- Execute within a container-like environment which handles low-level tasks such as caching, transaction management, and so on.
In this regard, BOs in the BOPF are not unlike objects developed in other component architectures (e.g. EJBs in Java, Microsoft COM+, etc.).
Anatomy of a Business Object
From a modeling perspective, BOs are made up of several different types of entities:
- Nodes
- Nodes are used to model a BO’s data.
- Nodes are arranged hierarchically to model the various dimensions of the BO data. This hierarchy is organized underneath a single root node (much like XML). From there, the hierarchy can be nested arbitrarily deep depending upon business requirements.
- There are several different node types supported by the BOPF. However, most of the time you’ll find yourself working with persistent nodes (e.g. nodes which are backed by the database). It is also possible to define transient nodes whose contents are loaded on demand at runtime. These types of nodes can come in handy whenever we want to bridge some alternative persistence model (e.g. data obtained via service calls).
- Each node consists of one or more attributes which describe the type of data stored within the node:
- Attributes come in two distinct varieties: persistent attributes and transient attributes. Persistent attributes represent those attributes that will be persisted whenever the BO is saved. Transient attributes are volatile attributes which are loaded on demand.
- A node’s attributes are defined in terms of structure definitions from the ABAP Dictionary.
- At runtime, a BO node is like a container which may have zero, one, or many rows. If you’re familiar with the concept of controller contexts with the Web Dynpro programming model, then this concept should feel familiar to you. If not, don’t worry; we’ll demonstrate how this works whenever we look at the BOPF API.
- Actions
- Actions define the services (or behavior) of a BO.
- Actions are assigned to individual nodes within a BO.
- The functionality provided by an action is (usually) defined in terms of an ABAP Objects class that implements the
/BOBF/IF_FRW_ACTION
interface. - To some extent, it is appropriate to think of actions as being similar to the methods of an ABAP Objects class.
- Associations
- Though BOs are designed to be self-contained, autonomous entities, they do not have to exist in isolation. With associations, we can define a direct and unidirectional relationship from one BO to another.
- For example, in just a moment, we’ll take a look at a sample BO called
/BOBF/DEMO_SALES_ORDER
which is used to model sales orders. Here, we’ll see how the product assignments for sales order items is defined in terms of an association with a product BO called/BOBF/DEMO_PRODUCT
. This composition technique makes it possible to not only leverage the product BOs data model, but also its behaviors, etc. - Associations allow us to integrate BOs together in complex assemblies à la Legos™.
- Determinations
- According to the aforementioned BOPF enhancement guide, a determination “is an element assigned to a business object node that describes internal changing business logic on the business object”.
- In some respects, determinations are analogous to database triggers. In other words, they are functions that are triggered whenever certain triggering conditions are fulfilled. These conditions are described in terms of a series of patterns:
- “Derive dependent data immediately after modification”
- This pattern allows us to react to changes made to a given BO node. For example, we might use this event to go clean up some related data.
- “Derive dependent data before saving”
- This pattern allows us to hang some custom logic on a given BO node before it is saved. This could be as simple as using a number range object to assign an ID value to a node attribute or as complex as triggering an interface.
- “Fill transient attributes of persistent nodes”
- This pattern is often used in conjunction with UI development. Here, we might want to load labels and descriptive texts into a series of transient attributes to be displayed on the screen.
- Note: This determination can be bypassed via the API if the lookup process introduces unnecessary overhead.
- “Derive instances of transient nodes”
- This pattern allows us to load transient nodes into memory on demand. Here, for example, we might lookup real-time status data from a Web service and load it into the attributes of a transient node from downstream consumption.
- “Derive dependent data immediately after modification”
- Determination patterns are described in detail within the aforementioned BOPF enhancement guide.
- The logic within a determination is defined via an ABAP Objects class that implements the
/BOBF/IF_FRW_DETERMINATION
interface.
- Validations
- According to the BOPF enhancement guide, validations are “an element of a business object node that describes some internal checking business logic on the business object”.
- Validations come in two distinct forms:
- Action Validations
- Action validations are used to determine whether or not a particular action can be executed against a BO node.
- Consistency Validations
- As the name suggests, consistency validations are used to ensure that a BO node is consistent. Such validations are called at pre-defined points within the BOPF BO transaction cycle to ensure that BO nodes are persisted in a consistent state.
- Action Validations
- The validation logic is encapsulated within an ABAP Objects class that implements the
/BOBF/IF_FRW_VALIDATION
interface.
- Queries
- Queries are BO node entities which allow us to search for BOs using various types of search criteria.
- Queries make it possible for consumers to access BOs without knowing the BO key up front.
- Queries also integrate quite nicely with search frameworks and the like.
- Queries come in two varieties:
- Node Attribute Queries
- Node attribute queries are modeled queries whose logic is defined within the BOPF runtime. These simple queries can be used whenever you simply need to search for BO nodes by their attributes (e.g. ID = ‘12345’).
- Custom Queries
- Custom queries allow you define your own query logic by plugging in an ABAP Objects class that implements the
/BOBF/IF_FRW_QUERY
interface.
- Custom queries allow you define your own query logic by plugging in an ABAP Objects class that implements the
- Node Attribute Queries
The figure below illustrates how all of these entities fit together within a BO node definition. Here, I’ve pulled up a BO called /BOBF/DEMO_SALES_ORDER
in Transaction /BOBF/CONF_UI. Here, the BO metadata is organized into several different panels:
- On the top left-hand side of the screen, you can see the BO’s node structure. Here, you can see that the node structure is organized underneath a top-level ROOT node which models sales order header data. Underneath this node are several child nodes which model sales order items, customer assignment, and texts. The ITEM node in turn encompasses its own child nodes to model item-level data.
- On the bottom left-hand side of the screen, we can browse through the node collection of a BO and view the entity assignments of a given node. As you can see in the figure, each node contains folders which organize assigned actions, validations, and so on.
- In the middle of the screen, we can view additional details about a selected node by double-clicking on a node within the Node Structure panel on the left-hand side of the screen. Here, we can look at a node’s data model, implementation classes, and so on.
We’ll have an opportunity to get a little more hands on with these entities in upcoming blog entries. For now, our focus is on grasping how pieces fit together and where to go to find the information we need to get started with a BO.
Next Steps
At this point, you should have a decent feel for how BOs are modeled at design time. In my next blog, we’ll shift gears and begin manipulating BOs using the provided BOPF APIs. This will help put all of these entities into perspective.
Queries are often misused at runtime, therefore just some small addition:
It's (almost) true that Queries identify a set of instance of the node at which they are modeled, but: (as per contract) they only return persisted data!
As during transactional processing it can happen, that instances which shall be found have just been created during the session, queries should not be used while implementing transactional entities (such as determination, actions, validations).
If a collection of instances has to be identified which can't be resolved via associations, alternative keys allow a translation of semantical attributes to technical keys.
Now you are wondering how a key can translate to a collection of keys? The answer is in the non-uniqueness of the key. E. g. a purchasing group can be thought of identifying a set of purchasing documents. It thus acts as a non-unique alternative key.
Cheers,
Oliver
P.s.:Excellent post, James! It's quite tricky to publish good non-redundant-content about BOPF after your series 🙂
I have some difficulties regarding the following statements, could you clarifiy these a bit?
Thanks for mentioning the non-unique alternative key to build up groups. So is it recommended to create groups by using the same GUID for an alternative group-key? or should the alt-key strictly be semantical in contrast to a purely technical GUID?
Cheers,
Kai
Hi Kai,
Regarding the first statement, what he's saying is that queries return a set of node rows for the node they're defined against. Here, you have to distinguish between the design time view of the BO model vs. the runtime view. At runtime, you can think of nodes as being rather like internal tables/containers which contain 0..n node rows. Queries fetch the node rows which match up with whatever query selection criteria specified.
The second point refers to the fact that queries are always performed against persistent data (i.e. node rows that have been persisted to the system database). With that in mind, he's saying that you wouldn't want to use a query to fetch the current state of a node within a transactional entity such as a determination or action. Why? Because there may be node rows existing in memory that wouldn't be accounted for in the query selection. For these kinds of tasks, we must use the BOPF API to fetch the complete set of node rows (in memory + persisted) and then filter the result set as needed based on our business requirements.
Does that help? Thanks.
that did indeed help, thanks!
Hi James Wood,
Can I have some information regarding the Configuration Object and how to create one...!
Thanks in advance.
Hi Malathesha,
The Configuration Object is an object that allows us to introspect metadata about a business object. This object implements the /BOBF/IF_FRW_CONFIGURATION interface which defines lots of methods to find out information about a given BOPF node (e.g., its name, data structures, defined associations, queries, etc.). In some respects, it's analogous to the RTTI classes you might have worked with such as CL_ABAP_STRUCTDESCR. In essence, it tells you everything you need to know about a business object's makeup. This leads to lots of interesting dynamic programming possibilities.
Getting your hands on a Configuration Object is pretty straightforward:
DATA lo_conf_obj TYPE REF TO /bobf/if_frw_configuration.
lo_conf_obj = /bobf/cl_frw_factory=>get_configuration( iv_bo_key = ? ).
Here, you need only pass in the business object key for whatever BO you're working with. This can be easily obtained using the SC_BO_KEY constant in the constants interface associated with your BO. Hope this helps.
Thanks,
James
Hi James,
Some how I am still not getting why would we need the configuration object. What is the use case?
And initially my assumptions were something like this. We use these configuration objects for maintaining customization, like how we maintain in SPRO. I thought this is something like that. (in BOPF world)
I still don't understand the option available in the BOBF to create BO of type Configuration Object.
Thanks,
Malathesha Sodad
Hi Malathesha,
I suppose this is not something you use every day. Where it really shows its value I think is in the development of frameworks. Some tangible examples of this include the FBI (FPM<->BOPF Integration) framework used to integrate the BOPF with FPM, integration of BOPF BOs in generic search screens or (POWL) work lists, BW extractors, etc. Here, I can build reusable components that can conceivably work with any BO provided the requirements aren't domain-specific.
Though it may not matter so much to end users, it matters a great deal to customers who invest in the BOPF because it makes the software much more flexible. For instance, if a customer has an FPM application built on the BOPF and they decide they want to move to an SAPUI5-based solution, nothing has to change at the model level. The customer just plugs in GBI (SAP Gateway<->BOPF Integration) and they're up and running. It's the BOPF's generalized API that makes this kind of portability possible.
Does that help?
Thanks,
James
Hi James,
No Still not.. As a developer I want to know the significance of having this option available. If this is something to be used internally then it should be some set of API's like what we have for the BRF+ with FDT classes.
I am able to create the BO of type configuration object. But I want to know how and where to use this particular type of BO.
As this show different BO Types. I am interested to learn each one of these type.
Thanks,
Malathesha
OK, I'm with you now. What you've depicted above is different from what I'm describing - a case of SAP sort of mixing terms a little bit. The object I mentioned is also called the Configuration Object in some circles, so I didn't catch your meaning at first.
This category of BO is defined as part of the BO schema in the /BOBF/OBM_BO table, but I personally haven't seen this category used in any live SAP system. Therefore, I would defer to the SAP employees working this forum to comment further on this.
Thanks,
James
Hi James,
Ok, But to make you little more clear about what I am talking, I just added an IMAGE. 🙂
Yes I don't see any of the BO's in the system with this category. I really have to find someone to get the better information about it.
Thanks a Lot..
Hi James!
Could you please have a look at
Want to put custom messages on click 'Check' button
Thank you!
Tushar C.