Generalization / Specialization

1
Hi, I would like to extend my domain model with a specialization. My Generalization_A entity already contains data and I want to extend that data with new data that will be stored in entity Specialization_B. When I create a new object based on Specialization_B, it will automatically create a related new object in Generalization_A, so for new objects it's not a problem. However I cannot find a way to edit the data in Specialization_B for EXISTING objects in Generalization_A. Is there any way to achieve this, other than retrieving the object from Generalization_A, create a new object Specialization_B (which leads to a new object Generalization_A) and delete the old object Generalization_A ? This is not an option due to the many existing associations to Generalization_A that would also need to be converted then.   Please advise. Thanks.
asked
3 answers
1

An alternative approach would be to avoid using specialisation (since you already have instances that you say would be impractical to change) and simple create a new 1-1 association to the “specialisation” entity. You have two objects instead of one to manage, but you have a lot of migration flexibility.

Regards

John

answered
0

Hey Elco,

So, if I am correct in understanding, you already have a table filled with generalizations? And you would like those to have attribute ¾ as well? What I think I see here is that there might be some confusion between database practise and the domain here. Yes, in the background, when creating a Specialisation_B, an object will also appear in the table for A, if I remember correctly. The implication for Mendix is quite different however. 

Very concretely: any instantiated object Generalization_A can never have attribute3 or 4 (if you create A in a Microflow, you will never see attributes 3/4); this is due to the nature of the Entity, which defines it should only have ½. In other words, there is no way to convert an Object A to an Object B. In order to achieve this, you will have to copy Object A into a newly created Object B, and delete the old source. You can do this using a Conversion microflow. It should do roughly the following things:

  • log start/end of the flow
  • retrieve all A's in ListA
  • retrieve all B's in ListB
  • subtract ListB from ListA → ListAWithoutBs (yes, ListA will also contain Bs, so they need to be subtracted).
  • create a commitListB
  • Loop over ListAWithoutBs, create a newObjectB forEach, and add to the commitListB, 
  • check if commitListB has any items, if so, delete ListAWithoutBs, commit commitListB.

 

That should give you the option to start extending your data.

Hope this helps. If it does, please mark as correct ;-)

Best regards,

Wouter 

answered
-1

No, not in a Mendix way to my knowledge. But thinking about this, brings up this idea: Make a Java call do that for you. Make it create the Specialization_B, modify that object’s attribute to point to Generalization_A by setting Specialization_B’s id to that of Generalization_A .

NB. this is a very good way to corrupt your database, so you might want to add a test or two.

 

Since this is great fun to do, I gave this a go. The setup:

The data:

The Subjects have an association to Teacher 1 or 2.

After creation of the SpecialSubject, it (actually: the new Subject) has no association to any Teacher, because I did not select one.

Now the idea is to:

  1. Change id of SpecialSubject to 64….569
  2. Change submetaobjectname of Subject 64….569 to test.SpecialSubject
  3. Delete Subject 116...685
  4. See if the database is not corrupted, and SpecialSubject has an association to Teacher 1

First try this manually….

UPDATE public."test$specialsubject" SET id=64176294690029569 WHERE id=116530640358211685;
UPDATE public."test$subject" SET submetaobjectname='test.SpecialSubject' WHERE id=64176294690029569;
DELETE FROM public."test$subject" WHERE id=116530640358211685;

Works like a charm. What a lovely way to spend my friday afternoon :-)

But, but, but. Although my application is running fine, it is likely to have some undesired side-effects because the ids are no longer sequential in entity SpecialSubject. New SpecialSubject-objects will get an id starting with 116… So i would not persue that path. Better would be to change step 1 to

  1. Change id of Subject to 116….658 and
  2. Go through all association tables and replace 64….569 by 116….658

Watch out, table locking issues ahead… Anyways, here ends my pondering. Back to the garden I go.

answered