ATTENTION ! This made me nervous.

In essence, the two classes are sharing the same data / Index / stream globals.

This means there is also
Parameter MANAGEDEXTENT As INTEGER = 0;
Otherwise, it wouldn't compile

Re-reading your question, I understand that properties in 
New_class are not identical and synchronized with Old_class ?
So even Storage Definition might be different ? 
IF YES, I'd say it's highly risky! 

  • With %OpenId you create a complete internal local copy of your object
  • With %Save it is written back as complete as is was. NOT just changed properties as you might expect And non- defined properties vanish
  • Any change that happened in between from some other process is lost
  • You may need some locking logic to prevent simultaneous access by 2 instances  eg. locking the Id for exclusive access by 1 single  process.
  • In your case it may even happen in 1 process with Old_Class vs, New_Class

Big Thanks for this recognition  ! 
Especially for the team that made it possible. 

💐 

Does it work without that UnitTest line in the Dockerfiles ??

 ([ $TESTS -eq 0 ] || iris session iris -U $NAMESPACE "##class(%ZPM.PackageManager).Shell(\"test $MODULE -v -only\",1,1)") && \

Running UnitTest directly in iris.script might be easier to control.
Checking UnitTests with ZPM manually after the first install might give more precise info of the problem
 

My personal approach would be:

  1. separate instance code from Class Methods
    This covers all properties and especially Calculated Properties
    Or simplified, all code tied to data storage
  2.  Class Methods work on referenced objects but have no dedicated data store (i%...)
    Simplified, they are code-only components.
  3.  Class Methods could be bundled in several Classes.

In Caché you had CacheParameterFile  cache.cpf with the SuperServerPort 1972
now it's named iris.cpf  with DefaultPort=1972

@Julius Kavay  hits the point:

true of false as system constants is breaking the rules and
the long-practiced idea and principles behind ISOS and before
@Joel Solon : isn't it ?) 

You may ask for $TRUE or $FALSE  system constant / variable

Until this, you are free to define your own $ZTRUE or $ZFALSE using
%ZLANGV00.mac to extend the language.
It's all ready for use to extend the language according to your needs and taste

Details on %ZLANG*

I fail to see the problem:

  • true:==> $$$OK
  • false:==> $$$NOTOK

do I miss siómething ?

Or is the intention to mix ISOS with JavaScript ???

Primary / Secondary  ?? Is this a shadowing configuration ?

Shadowing applies to the databases  IRIS.DAT, and Journal Files  
It doesn't shadow external "foreign" files like  .../Temp/QWhoZAwFF3f9jQ.iostream

If you use a custom class query %Library.Query type you may write your parameters to some
^mtemp.Evgeny($i(^mtermp.Egeny)) = ..... direct from the Execute method
or ^mtemp.Evgeny($h) = ....

For basic class query %SQL.Query () you may take the usual SQL approach

  • Create a SQL method that always returns 1 (TRUE)
  • You pass all your parameters into that method 
    • which does the ^mtemp trick and a QUIT 1
  • add to the WHERE clause  . . .  AND MYTRACE(par1,par2,---)=1

I refer to this a STATIC clause since it is only executed once by query
because of no reference to any column values 

It was my approach to SQL debugging
 

If your payload is received as a string 

set jsn={}.%FromJSON(payload)
write jsn.%Get("boolprop")

works without a persistent object

Class MyPackage.MyClass Extends (%Persistent, %JSON.Adaptor)
{
 Property JSONid As %Integer(%JSONFIELDNAME = "id");
 Property strprop As %String;
 Property boolprop As %Boolean;
}
                                                                           

next this worked

set jsn={  "id": 1,  "strprop": "string", "boolprop": true }
set sc=obj.%JSONImport(jsn)
zw obj
+----------------- general information ---------------
|      oref value: 2
|      class name: MyPackage.MyClass
| reference count: 1
+----------------- attribute values ------------------
|       %Concurrency = 1  <Set>
|             JSONid = 1
|           boolprop = 1
|            strprop = "string"
+-----------------------------------------------------

Probably because extending ObjectScript Functions in %LANGF00.mac is so simple for ages

ZLPAD(%txt,%len,%pad) quit $$lpad^%qarfunc(%txt,%len,%pad)
ZRPAD(%txt,%len,%pad) quit $$rpad^%qarfunc(%txt,%len,%pad)

and then

USER>s txt="robert"
USER>w $zrpad(txt,20,"*")
robert**************

USER>w $zlpad(txt,20,"*")
**************robert

$system.SQL.SetIdentityInsert(1) is deprecated and replaced by $system..SQL.Util.SetOption(IdentityInsert ,1) 
from class docs:>>>
https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.SQL.Util#METHOD_SetOption

IdentityInsert - Set the IDENTITY_INSERT option for this process. IDENTITY_INSERT
controls the ability of the user to specify a value for the IDENTITY property when
saving a new object, a value for the IDENTITY column, or an explicit ROWID value in an SQL INSERT.

Notes

  • Changing this configuration setting takes effect immediately and lasts for the duration of the process or until $SYSTEM.SQL.Util.SetOption("IsolationMode",pValue) is called again.
  • This is a per-process setting.

Sounds good to me 

Big THANKS!
A great improvement!
Especially useful for continuous repeating quality checks in OEX !

to be clear: 
USEEXTENTSET is great for very large tables where the top (with the ID) is many 
storage levels away from data blocks.
It's up to the dimension of your project if the eventual gain in speed pays off at all.
for small tables as we know from our samples, I doubt. 

As I expected, it's one of the new storage features that cause the irritation

/// Use hashed global names
Parameter USEEXTENTSET = 1

from docu  https://docs.intersystems.com/iris20253/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_storageglobals#GOBJ_storageglobals_hashed
When you set USEEXTENTSET to 1, each index is also assigned to a separate global, instead of using a single index global with different first subscripts. Again, this is done for increased performance.

Not explicitly mentioned - this also affects  IDKEY !

And the example presented shows in detail that 
IdLocation and DataLocation are NOT identical anymore, as it used to be for decades
 

You can get the required Global reference like this programmatically:

 ; get compiled class  with your classname
USER>set classname="oex.Dir"
USER>set dic=##class(%Dictionary.CompiledClass).%OpenId(classname)
 ; get relationship to CompiledStorage
USER>set stor=dic.Storages.GetAt(1)
 ; get name of the ID-Global
USER>Write stor.IdLocation
^oex.DirD
USER>

I'm surprised that   data is already imported via SQL but ^myclassD has no content.
So take a look into the related generated class:

Storage Default
{
<Data name="DirDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
- - - - - -
after all properties
</Data>
<DataLocation>^oex.DirD</DataLocation>
<DefaultData>DirDefaultData</DefaultData>
<ExtentSize>986</ExtentSize>
<IdLocation>^oex.DirD</IdLocation>
<IndexLocation>^oex.DirI</IndexLocation>

 <IdLocation> is the one to go for
with all the new Storage strategies (columnar, sharded, ...  )
This might be quite an exotic global name and rarely the traditional.

I was right. 
My 7* review in OEX is still blocked by OEX censors, and your stars are suppressed.
24hrs are promised for reviews in OEX.
Just found it published now  [2026-01-04 13:18:45 UTC]

Using methods inside the class instead of
The external MAC routine in the original code is an elegant and valid approach

Robert Cemper · Dec 31, 2025 go to post

Happy New Year!
Here is a draft version of ZPretty.mac for ISIS
I'm not sure if this is worth to be public at all.

ZPretty ; make JSON readable
#; input= JSON string 
Do(input) public {
    if $e(input)="{" do ##class(%JSON.Formatter).%New().Format(input)
    else  write "<UNDEFINED>"
    quit ""
    }
tst  public ; 
    set jsn={"Name":"Li,Robert K.","SSN":"672-92-9664","DOB":"1975-01-12","Home":{"Street":"986 Washington Blvd","City":"Boston","State":"PA","Zip":"95802"},"Office":{"Street":"6012 First Place","City":"Reston","State":"MT","Zip":"77739"},"Spouse":{"Name":"Avery,Zelda H.","SSN":"323-13-7437","DOB":"1943-03-27","Home":{"Street":"196 Main Drive","City":"Youngstown","State":"WY","Zip":"53229"},"Office":{"Street":"4056 Franklin Court","City":"Bensonhurst","State":"IA","Zip":"27688"},"FavoriteColors":["Black"],"Age":77},"Age":45,"Title":"Associate Marketing Manager","Salary":10421}
    quit jsn 
Robert Cemper · Dec 31, 2025 go to post

I run iris.script at docker start in this demo :  UDP
see docker-compose.yml.
It's for 2 containers. In your case half of it would be enough.