Skip to main content

Opening Saved Objects

Opening Saved Objects

To open an object (load an object instance from disk into memory), use the %OpenId() method, which is as follows:

classmethod %OpenId(id As %String, 
                    concurrency As %Integer = -1, 
                    ByRef sc As %Status = $$$OK) as %ObjectHandle

Where:

  • id is the ID of the object to open.

    In these examples, the ID is an integer. See The Object ID for information on other options

  • concurrency is the concurrency level (locking) used to open the object.

  • sc, which is passed by reference, is a %StatusOpens in a new tab value that indicates whether the call succeeded or failed.

The method returns an OREF if it can open the given object. It returns a null value ("") if it cannot find or otherwise open the object.

For example:

 // Open person "10"
 Set person = ##class(Sample.Person).%OpenId(10)

 Write "Person: ",person,!    // should be an object reference

 // Open person "-10"
 Set person = ##class(Sample.Person).%OpenId(-10)

 Write "Person: ",person,!    // should be a null string

You can also use the %Open() method, which requires an OID rather than an ID. An OID is a permanent identifier unique to the database that includes both the ID and the class name of the object. For more details, see Identifiers for Saved Objects: ID and OID.

To perform additional processing that executes when an object opens, you can define the %OnOpen() and %OnOpenFinally() callback methods. For more details, see Defining Callback Methods.

Multiple Calls to %OpenId()

If %OpenId() is called multiple times within an InterSystems IRIS process for the same ID and the same object, only one object instance is created in memory. All subsequent calls to %OpenId() return a reference to the object already loaded into memory.

For example, consider this class featuring multiple %OpenId() calls to the same object:

Class User.TestOpenId Extends %RegisteredObject
{

ClassMethod Main()
{
   set A = ##class(Sample.Person).%OpenId(1)
   write "A: ", A.Name

   set A.Name = "David"
   write !, "A after set: ", A.Name

   set B = ##class(Sample.Person).%OpenId(1)
   write !, "B: ", B.Name

   do ..Sub()

   job ..JobSub()
   hang 1
   write !, "D in JobSub: ", ^JobSubD
   kill ^JobSubD

   kill A, B
   set E = ##class(Sample.Person).%OpenId(1)
   write !, "E:", E.Name
}

ClassMethod Sub()
{
   set C = ##class(Sample.Person).%OpenId(1)
   write !, "C in Sub: ", C.Name
}

ClassMethod JobSub()
{
   set D = ##class(Sample.Person).%OpenId(1)
   set ^JobSubD = D.Name
}

}

Calling the Main() method produces these results:

  1. The initial %OpenId() call loads the instance object into memory. The A variable references this object and you can modify the loaded object through this variable.

       set A = ##class(Sample.Person).%OpenId(1)
       write "A: ", A.Name
    

    A: Uhles,Norbert F.

       set A.Name = "David"
       write !, "A after set: ", A.Name
    

    A after set: David

  2. The second %OpenId() call does not reload the object from the database and does not overwrite the changes made using variable A. Instead, variable B references the same object as variable A.

       set B = ##class(Sample.Person).%OpenId(1)
       write !, "B: ", B.Name
    

    B: David

  3. The third %OpenId() call, in the Sub() method, also references the previously loaded object. This method is part of the same InterSystems IRIS process as the Main() method. Variable C references the same object as variables A and B, even though those variables are not available within the scope of this method. At the end of the Sub() method, the process returns back to the Main() method, the variable C is destroyed, and variables A and B are back in scope.

       do ..Sub()
    
    ClassMethod Sub()
    {
       set C = ##class(Sample.Person).%OpenId(1)
       write !, "C in Sub: ", C.Name
    }

    C in Sub: David

  4. The fourth %OpenId() call, in the JobSub() method, is run in a separate InterSystems IRIS process by using the JOB command. This new process loads a new instance object into memory, and variable D references this new object.

       job ..JobSub()
       hang 1
       write !, "D in JobSub: ", ^JobSubD
       kill ^JobSubD
    
    ClassMethod JobSub()
    {
       set D = ##class(Sample.Person).%OpenId(1)
       set ^JobSubD = D.Name
    }

    D in JobSub: Uhles,Norbert F.

  5. The fifth %OpenId() call occurs after deleting all variables (A and B) that reference the loaded object in the original process, thereby removing that object from memory. As with the previous %OpenId() call, this call also loads a new instance object into memory, and variable E references this object.

       kill A, B
       set E = ##class(Sample.Person).%OpenId(1)
       write !, "E:", E.Name

    E: Uhles,Norbert F.

To force a reload of an object being loaded multiple times, you can use the %Reload() method. Reloading the object reverts any changes made to the object that were not saved. Any previously assigned variables reference the reloaded version. For example:

 set A = ##class(Sample.Person).%OpenId(1)
 write "A: ", A.Name // A: Uhles,Norbert F.
 
 set A.Name = "David"
 write !, "A after set: ", A.Name // David
 
 set B = ##class(Sample.Person).%OpenId(1)
 write !, "B before reload: ", B.Name // David

 do B.%Reload()
 write !, "B after reload: ", B.Name // Uhles,Norbert F.
 write !, "A after reload: ", A.Name // Uhles,Norbert F.

Concurrency

The %OpenId() method takes an optional concurrency argument as input. This argument specifies the concurrency level (type of locks) that should be used to open the object instance.

If the %OpenId() method is unable to acquire a lock on an object, it fails.

To raise or lower the current concurrency setting for an object, reopen it with %OpenId() and specify a different concurrency level. For example,

 set person = ##class(Sample.Person).%OpenId(6,0)

opens person with a concurrency of 0 and the following effectively upgrades the concurrency to 4:

 set person = ##class(Sample.Person).%OpenId(6,4)

Specifying a concurrency level of 3 (shared, retained lock) or 4 (shared, exclusive lock) forces a reload of the object when opening it. For more information on the possible object concurrency levels, see Specifying Concurrency Options.

FeedbackOpens in a new tab