Smythe Smythee · Nov 16, 2022

How to get values from a serialobject class



want to get the values from a serial property because my code depends upon the class serial class.

For example

Serial class

Class Data.Serial Extends %SerialObject


Property FirstName as %String;

Property LastName as %String;


Persistent class

Class Data.Persistent Extends %Persistent


Property MPID as %Integer;

Property Name as Name.Serial;


Now i need save MPID and Name(Serial class property into SQL Table ) so i am trying the below class

Class Data.TestUtil Extends %RegisteredObject


Method Savedata(MPID,FirstName,LastName)


Set tSC=0

Set Obj=##Class(Data.Persistent).%New()


Set Obj.FirstName=FirstName
Set Obj.LastName=LastName

Set tSC=Obj.%Save()

Quit tSC



But data is not getting saved into SQL data and throwing an error, How to save serial class Property into the SQL table?



Product version: Ensemble 2018.1
$ZV: Cache for Windows (x86-64) 2018.1.1 (Build 312_1_18937U) Fri Apr 26 2019 17:58:36 EDT
0 326
Discussion (10)1
Log in or sign up to continue

If your serial class is named Data.Serial (as in your example code) then you should use the same name for the serial property too

Class Data.Persistent Extends %Persistent
Property MPID as %Integer;
Property Name as Data.Serial;   <--- !!!!!

The correct way to set the values

Set Obj=##Class(Data.Persistent).%New()
Set Obj.Name.FirstName=FirstName   ; <----
Set Obj.Name.LastName=LastName     ; <----
Set tSC=Obj.%Save()

Hi ,

I gave the example of the scenario i am using in my code but i am getting  Invalid Oref error


ERROR <Ens>ErrException: <INVALID OREF>zDischarge+3^CUSTOM.SQL.TestUtil.1 -- logged as '-' number - @' Set Obj.Discharge.DischargeFlag=DischargeFlag'"

your example has neither a Property Discharge
nor as Serial object Discharge with a Property DischargeFlag
<INVALID OREF> refers to the missing Property as SerialObject

It seems you try to create properties and substructures similar to JSON.
You have to define everything in advance before you can use it.

The below way is working for me when i am creating a new row in my SQL table 

Set Obj=##Class(Data.Persistent).%New()
Set Obj.Name.FirstName=FirstName   ; <----
Set Obj.Name.LastName=LastName     ; <----
Set tSC=Obj.%Save()


But my requirement is update tha values in the existing row so i am opening the object and saving the values. In this case iam getting error

Set Obj=##Class(Data.Persistent).%OpenID(value)
Set Obj.Name.FirstName=FirstName   
Set Obj.Name.LastName=LastName    
Set tSC=Obj.%Save()

When i am opening particular object in table i am getting the error 

the method to open is
Set Obj=##Class(Data.Persistent).%OpenId(value)

COS is case sensitive

Ok,After changing to this line "Set Obj=##Class(Data.Persistent).%OpenId(value)"

same facing the INVALID OREF Error 

check if your value is an existing Id  after the %OpenId

if 'Obj do $system.OBJ.DisplayError()
else  zwrite Obj

so you see what's going on

I tried these steps in my environment got this ERROR #5809: Object to Load not found 

the above steps are working when i am using %New() and getting error while using opening id %OpenId

that simply means that value doesn't contain a valid object id.

You may see valid ids  running 

most likely some integer

Some comments to %New() and %OpenId() methods.  A simple

set obj=##class(Some.Class).%New()

succeeds (in general) always. On the other hand, for

set obj=##class(Some.Class).%OpenId(rowId)

there are several reasons, not to succeed:
- the given rowId does not exists
- when data is stored in multiple nodes and the rowId is locked
- the internal storage structure is damaged (setting the data global by hand, improper changing the storage structure, etc.)

Hence, the correct modus operandi is

set obj=##class(Some.Class).%OpenId(rowId)
if 'obj do $system.OBJ.DisplayError() quit

// from here on, you can use the opened object

As Mr Cemper suggested, you could run an SQL select to find out the existing rowIds or alternatively, you could do a check before opening the object

if ##class(Some.Class).%ExistsId(rowId) { write rowId," exists" } else { write rowId," unknown" }