Thanks for the reply. How can my unit test configure a BPL process to call my mock operation instead of the real operation? Do I have to rewrite the business process to use indirection in the target of each <call> element and make the target a custom setting on the business host?

I don't know of anything similar to Hibernate in Caché. If you want to encapsulate some data access logic inside of a class, it's helpful to define a class query that other objects can access through dynamic SQL.

More specific to your getByCode example, I use the index auto-generated methods a lot. For example in your dictionary table I would create a unique index on Code Index CodeIndex On Code [ Unique ]; and then use ##class(Whatever.Dictionary).CodeIndexOpen() to open the object I want.

I've had this problem before where scheduled tasks just stopped running, but if I ran ##class(%Sys.Task).CheckSchedule() all the previously scheduled tasks would run once. Restarting my Ensemble instance fixed it. I recommend contacting support if this recurs.

Hi Pilar,
Here's an example call using password grant that works for me. You might have to change the endpoint depending on your OAuth server configuration.

POST /oauth2/token
Content-type: application/x-www-form-urlencoded

This authenticates the user and returns JSON with the access token as expected.

Here's the code I'm using to test btw. If you uncomment the commented line it gives the SAX parser error.

Class XML.Sample2 Extends (%RegisteredObject, %XML.Adaptor)

Property StringEmpty As %String;

Property StringZerowidth As %String;

Property IntegerEmpty As %Integer;

Property IntegerZerowidth As %Integer;

Property BoolTrue As %Boolean;

Property BoolFalse As %Boolean;

Property BoolZerowidth As %Boolean;

ClassMethod Test() As %Status
    set sample = ..%New()
    set sample.StringEmpty = ""
    set sample.StringZerowidth = $c(0)
    set sample.IntegerEmpty = ""
    //set sample.IntegerZerowidth = $c(0)
    set sample.BoolTrue = 1
    set sample.BoolFalse = 0
    set sample.BoolZerowidth = $c(0)
    set writer = ##class(%XML.Writer).%New()
    set string = writer.GetXMLString()
    w !, string
    set reader = ##class(%XML.Reader).%New()
    do reader.Correlate("sample","XML.Sample2")
    do reader.Next(.object, .sc)
    for prop = "StringEmpty","StringZerowidth","IntegerEmpty","IntegerZerowidth","BoolTrue","BoolFalse","BoolZerowidth" {
        write !, prop, ": ", $replace($property(object,prop),$c(0),"$c(0)")
    return $$$OK


Thanks, that might work. Is there any danger of the ID from CachéStorage getting reused if an entry gets deleted?

We're uniting this person+holiday table with a different table of personal time off to create a general absences table. Client applications access this table through a web service in order to sync a schedule. They need a GUID on each absence entry so they know what needs to be updated. For example, if a holiday changes there's an absence for each person in that country, and the client needs to update each of those entries.

We're only sending across the absences that have been updated since the last sync, so the client can't just rebuild the whole schedule every time.

We have a table for holidays and for people. Both of these tables have a country column. Each country has a list of holidays and all the people in that country have all those holidays off. The result of the join means semantically: which people have which days off. I could create a third table for this but it would have to be updated any time a holiday or a person gets added.


Your suggestion of using a hash function is good, and I think I'll do that.

Currently we're using the GUID from one of the tables, but the problem is it's not unique anymore after the join.

Good thought, but I should have mentioned that the GUID for a specific row needs to stay the same over multiple calls of the query.