Why can I not 'Assign' request directly to a context variable ?

I am rather new to ObjectScript and I have a query about assigning values to the context.

In  BPL I have a context variable (A08Msg) which is set to type Enslib.HL7.Message, I want to put my inbound HL7 message into this variable so I tried:

  • an Assign to set context.A08Msg to request

This seemed to load the message into the variable because I could read values, e.g. using  context.A08Msg.{PD1:3(1).1} , but I was unable to write to context.A08Msg.

As an alternate method I built a dummy transform that transformed request into context.A08Msg , using this methodI was able to both read and write to context.A08Msg.

I would prefer not to have dummy DTLs laying around and so I was wondering if anyone could explain why I can transform into a context variable but not just assign into it, (my suspicion is that maybe I am dealing with pointers/OREFs).

Could anyone help me understand what is going wrong here,  and suggest how I can load the incoming 'request' into the context variable and be able to write to it without a DTL?

Thanks, Andy 

  • 0
  • 0
  • 206
  • 4
  • 3

Answers

Messages dequeued from another business host will have the IsMutable property set to false. Creating a clone of the message with the %ConstructClone() method or creating a new message object via a DTL will give you something you can update.

Thank you Jeffrey ... that totally correlates with the behaviour I am seeing. 

I have tested and assigning  request.%ConstructClone(1) to my context variable does indeed give me an object I can write to.

My Thanks go out to all concerned.

Your message might be locked by some other process at that time. 
Try to raise your Lock level to have exclusive access to your persistent object  %GetLock(id) which you need during %Save()
 If it fails you should find out who else is locking it. 

 but I was unable to write to context.A08Msg.

How did you determine that?

Generally it's not a good idea to pass whole objects received from somewhere else, especially if they could be changed down the road. If we're talking about persistent objects then they have ids and all references to persistent objects are stored as ids in the database. At runtime the id is read and the object is loaded into memory as required.

Ensemble BPL process is a state machine that loads and unloads context to/from disk often, so if some other Ensemble host changes the object it would also change in the base BP after reload cycle and that can cause problems.

As a workaround you can assign clones, that is safe:

<assign property='context.A08Msg' value='request.%ConstructClone(1)'/>

Thanks Eduard,

I determined that I could not write by later in the BPL assigning a value to context.A08Msg.{PD1:4(2).1} which did not save the changes; however,  when I changed the BPL to load context.A08Msg by calling a Transform  - a DTL which simply passed the source (request) to the target(context.A08Msg) - then the assign to context.A08Msg.{PD1:4(2).1} worked as expected.

I suspect the problem lies in the fact that request is an ens.request object while A08Msg is an EnsLib.HL7.Message object (as Robert suggested, but which does not seem to have been added as a comment).

Thanks for the response, I will try the request.%ConstructClone(1) method to see what effect this has.

Comments

Thanks for the answers Robert. 

It is a valid point when you mention the object type... my context.A08Msg was set to Enslib.HL7.Message whereas the request type is ens.Request; this could explain why I could not simply assign the request directly into context.A08Msg? 

Could I look 'inside' the request object to find the HL7 message payload? 

Typically a Message in Ensemble is inheriting from Ens.Request
e.g. Class EnsLib.Testing.Request Extends Ens.Request

I have no Healthshare at hands to identify your correct message
just to confirm 
Enslib.HL7.Message does NOT extend Ens.Request as it is a  Persistent object on it's own.