CodamAIDocs
Topicdone

Cycle protection

How CDMS prevents nested reading or writing from going around in circles.

Variants
Reading: as deep as the responseReading: A → B → AWildcards stop at the idWriting: the back reference is skippedWriting: each object onceinternal field _reference

What this is about

Relations point in both directions: the company knows its employees, and each employee knows their company. If a program blindly follows all relations, it goes around in circles: company → employee → company → employee … This is called a cycle.

flowchart LR
    A["Company"] -->|employees| B["Employee"]
    B -->|company| A
    B -.->|"CDMS stops here"| X(("■"))

When reading: the response is the limit

CDMS only follows a relation if you expand it in the response. You have to write out each level yourself. Because your response is finite, so is the answer.

There and back: A → B → A → B
Request
POST /api/rest/group/read/a1…
{
  "response": ["name",
    { "field": "children", "response": ["name",
      { "field": "parent", "response": ["name",
        { "field": "children", "response": ["name"] }
      ] }
    ] }
  ]
}
Response
{
  "data": {
    "name": "A",
    "children": [
      { "name": "B",
        "parent": {
          "name": "A",
          "children": [ { "name": "B", "children": null, "parent": null } ]
        }
      }
    ]
  },
  "meta": { "error": false }
}

As you can see, A and B appear more than once. CDMS does not merge them. It returns each level the way you asked for it. On the last level, children and parent are null, because you did not ask for them there.

How far CDMS goes when reading
Wildcards + and *
one level
  • + returns no relations
  • * returns relations only with their id
  • no expansion, so no cycle either
Expanding with { field, response }
as deep as written
  • each level is in your response
  • ways back like A → B → A are allowed
  • the same objects can appear more than once

More about expanding in Expanding references and lists.

When writing: back reference and each object once

With nested writing, CDMS could also go around in circles: the company writes its employees, and each employee has a field company that points back to the company. Two rules prevent this:

PUT on a company with employees
  1. 1
    CDMS
    writes the company and gets to the field employees
  2. 2
    CDMS
    writes Anna, a child in employees
  3. 3
    CDMS
    gets to the field company on Anna, so back to the company
  4. 4
    CDMS
    skips the back reference: the parent object sets the link itself, on both sides
  1. The back reference is not followed. From a child, CDMS does not go back to the parent object. It sets the link from above. If the child still contains a back reference, the parent object wins. See Both sides of a relation.
  2. Each object of the request is processed only once. For this, CDMS internally marks which objects it has already handled. The mark is stored in the internal field _reference.

The field _reference

_reference is an internal marker that CDMS uses only while it processes a request. In read responses, it appears as "_reference": null.

Handling _reference in the client
SituationWhat you do
in a read responseignore it, do not evaluate it
when writingyou may leave it in: CDMS discards a _reference you send and sets its own marker

The marker belongs to the server. If you send a read object back, the _reference in it does no harm — CDMS does not accept it. Only what CDMS sets itself while processing counts.

Pitfalls

Where to go next

Sources in the code and the knowledge base
  • CDMS/cdms-system-layer – AbstractLayer.recursiveRead, fetchAndSetModel, fetchAndSetList (depth follows the response); recursivePrepare (_reference), recursiveUpdate (excludeField), setReference
  • CDMS/cdms-rest-api – Expander (resolving the response, wildcards)
  • CDMS/cdms-integrationtest – probe against Group (parent/children)
  • documentation/30-daten-und-persistenz/03-beziehungen.md
Search