/ Development  

Transform PRD with this advanced technique to make entities abstract

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

Recognize this case? You build a beautiful solution on the AppWorks platform and now your analyst guy/gal asks you the question to generalize it. With the generalization feature it should be possible to build a “Generic” case and create new “Specific” cases with inherited building blocks. A great thought, but what happens with your production data when we decide our ‘Case’ entity must be flagged as “Abstract”…Now we’re talking! 🤠

Let get right into it…

For this post, we start with a simple project in your workspace. Name it whatever you want; I’m already prepared with a project prj_aw_tips_gen…What a coincident!? 😜 In this project, I create a simple ‘Case’ entity with just one case_name property and the basic generated BBs. To make it a bit challenging, I also add a ‘Lifecycle’ BB and the ‘Security’ BB. The lifecycle can be a 3-step phase “Draft”, “For Review”, and “Final” and the security contains the ‘Identity User’ with all marks applied.


FYI, I build with awdev and test with awtest (only applied with the ‘Entity Runtime User’ role!)

Time for a first publication and creating instances of our ‘Case’ entity. With the lifecycle BB in place, you will see lifecycle instances passing by in the Case Instance Manager artifact standing in ‘Draft’ (as we didn’t apply activities in the lifecycle states!).

Now, your analyst comes to your desk with a valid question to make the case “Generic” so other case types can “onboard” in the solution. So, we have a choice to make…?

Make the ‘Case’ entity “Abstract”

Have a look again at the previous screenshot…You see the ‘Abstract’ option in the right panel! Well, mark it and publish it! In runtime? You make the conclusion that new ‘Case’ instances can’t be created anymore; The old instances are still in place! A party 🎉…These instances can follow the old pathway and in the meantime, we onboard a new type of case with name ‘Case HR’! How? Well, let’s build it!

Create a new project with name prj_aw_tips_hr, with namespace folder and an entities folder looking like this:


The next step is creating a new ‘subtype’ entity from our generic ‘Case’…


See that all building blocks (grayed-out) are inherited; save the entity in our new project:


Now, do a first publication and check the runtime? hmmmm…nothing changed!? Or better, I don’t see it with my awtest account; my awdev can now create new ‘Case HR’ instances falling in the exact same ‘All cases’ list! Aha, that’s a security-thing! Time to replace the inherited security with our own security:


Edit the security and remark the correct settings for the already available ‘Identity User’ role; You will start to see ‘Revert’ arrows after this change, so it looks like we’ve just reinitialized the security specifically for our new entity. After a publication? Yes, my friend…I can create instances with my awtest account!

I’m uncertain if this “replace” action falls in the ‘Bug’ category or the ‘Feature’ category!?

How to continue from here? Well, build your HR process with a replacement of the lifecycle and add other building blocks to fulfill all requirements!

Now, your analyst guy/gal comes with a new “Onboarding” case type: Case Person. You get a solid confirmation this case follows the exact same process of our abstract case entity! So, A choice to make; Do we create a new subtype case_person from our abstracted ‘Case` and build a new project around it…ORRRR, do we communicate that we already have a ‘Case’ entity which we can un-abstract to make it fly again and tell the business to use this generic entity!?

Keep the ‘Case’ entity “as-is”

It’s time to un-abstract our entity and revert it to the ‘as-is’ state. Can we do this without any consequence in runtime? Well, do it, publish it, and check the runtime! WHAT? It works like a charm! 🤗


Yes, I updated my ‘All cases’ list with an identity ‘Entity type’ column to see the difference.

One interesting question left for now! What is happened with the replaced security BB on the ‘Case HR’ type? Well, this is still in place and works exactly the same. I also did a revert (to get a real inheritance situation again) and I was not able to do anything with it in runtime…As expected!

What happens in the database?

For the deep divers under us, a query on our entity table:
SELECT id, case_name, s_discriminatorid FROM o2aw_tipsgenericcase;

This is the result:


Yes, the instances are saved in the same table! When you find this interesting, this should also raise your DB-heartbeat:

-- Noob statement
SELECT DISTINCT s_elementid,
FROM s_elementdefinitions
WHERE s_name IN ('case',

-- Novice statement
SELECT DISTINCT aw_elements.s_elementid,
FROM o2aw_tipsgenericcase aw_case,
s_elementdefinitions aw_elements
WHERE (aw_case.s_discriminatorid = aw_elements.s_elementid
OR aw_case.s_discriminatorid IS NULL)
AND aw_elements.s_name IN ('case',

-- Expert statement
SELECT 'You can do much better; I''m not the database expert here!' AS comment
FROM o2aw_tipsgenericcase LIMIT(1);

A small post, but high-valuable in content with an interesting insight on inheritance, abstraction, replacement, and reversion! It’s a “DONE” with also a short dive into the database with a fascinating view what’s happening there! Add your thoughts in the comments section below, and I see you in a next great post on AppWorks tips…Have a great weekend too.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?