Question
· Apr 4, 2020

How to use subclasses (type cast)

Hello community,

I recently started to work with Ensemble. I defined a subclass of EnsLib.HL7.Message.  In my production I receive HL7v2 messages and transport them using the Message Router to a business operation. The operation class has an OnMessage method with parameter

pObject As MySubclassOfEnsLibHL7Message.

I expected that specifying the parameter type, on receiving the message an implicit type cast would be performed. However, $CLASSNAME reveals that my messages are still of type EnsLib.HL7.Message. How can I convert my messages in ObjectScript (without DTLs or something the like)?

My motivation for doing all of this is the following. I need to store copies of certain messages in a separate database, not in EnsLib_HL7.Message, where all the other messages are stored. So I thought the most intuitive way to achieve this would be to define the abovementioned subclass. Is there a better way to do this?

Any help is very much appreciated. Thank you in advance.

Discussion (7)1
Log in or sign up to continue

If I understand you correct you expect something  like

INSERT INTO new.MESSAGE (SELECT * from  EnsLib.HL7.Message  where id = ? )

this may work for rather modest designed relational tables but I doubt it will work for some complex structure as EnsLib.HL7.Message .

Subclassing is not the way to solve your problem for 2 reasons:

  • A subclass has always to match the .IsA() class type of its parent    (e.g. Employee as subclass of Person. Employee is also always a Person)
  • SubClasses share the storage with its parent. There are dirty tricks to avoid this but I assume you do not intend to change  EnsLib.HL7.Message.

There are ways to do something like this if you fiddle around in the storage structures. 
BUT: for reasons of transparency, documentation, and maintainability
I'd strongly recommend to use DTL. 


Fiddling around with COS in Ensemble is a rather tricky exercise.
Based on practical experience I can confirm that your successors will never forget you.

Thank you, Robert Cemper.

In fact, I now do something like your line of inline sql: I retrive my messages from the general EnsLib.HL7.Message database using their id. Although I liked the idea of setting up my own table, I suspect this is not how the system is intended to be used.

I surely did not want to mess with The Enslib message class. The documentation also hinted to some (can't judge if dirty) tricks to do this, but I'd rather not risk crashing the whole system...

Instead of subclassing I now use routing of messages by means of their values (message type, certain textual data) to distinguish different messages.

I hope this works out. What is COS, by the way?

Hi Abel,

When we subclass a persistent class and we need that this subclass have a own storage we need to add in the inheritance class list the %Persistent class  first of all classes.

Shared storage

 Class sample.MyHL7 Extends EnsLib.HL7.Message
{ 

Storage Default
{
<Type>%Library.CacheStorage</Type>
}

}

Own storage

 Class sample.MyHL7 Extends (%Persistent, EnsLib.HL7.Message)
{ 

Storage Default
{
<Data name="MyHL7DefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>ParentId</Value>
</Value>
<Value name="3">
<Value>DocType</Value>
</Value>
<Value name="4">
<Value>Envelope</Value>
</Value>
<Value name="5">
<Value>Source</Value>
</Value>
<Value name="6">
<Value>IsMutable</Value>
</Value>
<Value name="7">
<Value>OriginalDocId</Value>
</Value>
<Value name="8">
<Value>MessageTypeCategory</Value>
</Value>
<Value name="9">
<Value>TimeCreated</Value>
</Value>
</Data>
<Data name="UserValues">
<Attribute>UserValues</Attribute>
<Structure>subnode</Structure>
<Subscript>"UserValues"</Subscript>
</Data>
<DataLocation>^sample.MyHL7D</DataLocation>
<DefaultData>MyHL7DefaultData</DefaultData>
<IdLocation>^sample.MyHL7D</IdLocation>
<IndexLocation>^sample.MyHL7I</IndexLocation>
<StreamLocation>^sample.MyHL7S</StreamLocation>
<Type>%Library.CacheStorage</Type>
} 

}