Update Entities

The Entities API also allows you to update already existing entities through the endpoint: /entities/:entityName/:entityId with the HTTP method PUT.

Update an Entity

When the entity is updated successfully, the HTTP response status code 200 - OK is returned. By default, a JSON metadata representation of the entity is returned mainly containing the id attribute for further reference.

Here is an example of how to update an entity:

Create Customer Request
PUT http://localhost:8080/rest
            /entities
            /sample_Customer
            /13f01f59-8e5f-4fd9-802b-66501d49ac99

{
  name: "Updated Name"
}
Response: 200 - OK
{
  "_entityName": "sample_Customer",
  "_instanceName": "Updated Name",
  "id": "13f01f59-8e5f-4fd9-802b-66501d49ac99"
}

The Update Entity API behaves similarly to the Create Entities API regarding validation and entity references. The main difference is how 1:N associations and compositions are handled. The endpoint also allows you to partially update entities by only having those attributes in the request JSON.

Association Attributes

In case you want to update a 1:1 or N:1 association attribute, it is enough to send the new ID of the entity to reference. For 1:N or M:N associations an updated list of entity references changes what the entity is associated to.

The Update Entity endpoint will replace the existing association collection for a 1:N or M:N association with what is part of the request. For every entity reference that is not part of the request, the reference will be removed. But, the entity that has been referenced will not be deleted from the database.

In this example, you will see how to update an M:N association between Product and ProductTag. Assuming that the stored Product before the update looks like this:

Existing Product
{
  "id": "e1d586b4-aefb-2ee7-3b91-b07357b178ea",
  "price": 99.95,
  "name": "Outback Power Remote Power System",
  "version": 1,
  "tags": [
    {
      "id": "333f3a20-c47b-4bc9-ba34-a72d2d815695",
      "name": "shiny"
    },
    {
      "id": "c4c028f0-fec1-7512-83cd-c17537d1f502",
      "name": "great"
    }
  ]
}

In this example you would like to change the tags of the Product in the following ways:

  • great should be removed from the tags.

  • amazing should be added to the tags.

  • The tag shiny should be kept.

Update Tag Associations Request
PUT http://localhost:8080/rest
            /entities
            /sample_Product
            /e1d586b4-aefb-2ee7-3b91-b07357b178ea
            ?responseFetchPlan=product-with-tags

{
  "name": "123",
  "price": 99.95,
  "tags": [
    {
      "id": "333f3a20-c47b-4bc9-ba34-a72d2d815695" (1)
    },
    {
      "id": "d6ab132e-a0bd-a624-c6ad-cc544e83c584" (2)
    }
  ]
}
1 The ID of the product tag shiny is part of the request to keep the association.
2 The ID of the product tag amazing is newly added to the association.
As the ID of the product tag great (c4c028f0-fec1-7512-83cd-c17537d1f502) is not part of the request anymore, it will be removed from the association.
Response: 200 - OK
{
  "id": "e1d586b4-aefb-2ee7-3b91-b07357b178ea",
  "createdBy": "admin",
  "price": 99.95,
  "name": "Outback Power Remote Power System",
  "version": 2,
  "tags": [
    {
      "id": "333f3a20-c47b-4bc9-ba34-a72d2d815695",
      "name": "shiny" (1)
    },
    {
      "id": "d6ab132e-a0bd-a624-c6ad-cc544e83c584",
      "name": "amazing" (2)
    }
  ]
}
1 The shiny reference is still there, as it was part of the request
2 The amazing reference has been added, whereas the tag great is not part of the association anymore.
Remove *:1 Entity References

To remove a reference for N:1 or 1:1 associations, you need to send in null as a value. The absence of the attribute in the request will not lead that the reference is removed, because of the Partial Updates feature. In this case, the attribute would just be ignored and not changed as part of the request.

Composition Attributes

In case you want to update a Composition attribute, it is possible to directly update the content of the child entity as part of the update request for the parent entity. This is true for 1:1 as well as 1:N compositions.

the Update Entity endpoint will replace the existing composition collection with what is part of the request. For every entity reference that is not part of the request, the reference will be removed. Moreover, the entity that has been referenced before will be deleted from the application as well.

In this example, you will see how to update a 1:N composition between Order and OrderLine. Assuming that the stored Order before the update looks like this:

Existing Order
{
  "id": "288a5d75-f06f-d150-9b70-efee1272b96c",
  "date": "2021-03-01",
  "amount": 130.08,
  "lines": [
    {
      "id": "a1cd778b-fe49-4c74-05a0-6fb207dc11bd",  (1)
      "product": {
        "id": "1860904a-5444-9c3e-9dc1-1d7a26d9ac19",
        "name": "Solar-One HUP Flooded Battery 48V"
      },
      "quantity": 2.0,
      "version": 1
    },
    {
      "id": "55b925e5-9f3a-a725-9eb3-1240f9c1fe95",  (2)
      "product": {
        "id": "1ed85c7a-89f1-c339-a738-16307ed6003a",
        "name": "Cotek Battery Charger"
      },
      "quantity": 1.0,
      "version": 1
    }
  ],
  "version": 1,
  "customer": {
    "id": "f88597ff-009d-1cf2-4a90-a4fb5b08d835",
    "name": "Randall Bishop"
  }
}
1 The first order line references the Solar-One HUP Flooded Battery 48V product.
2 The second order line references the Cotek Battery Charger product.

In this example you would like to change the order lines in the following ways:

  • The quantity of the Order Line with the product Solar-One HUP Flooded Battery 48V should be increased to 3.0.

  • The order line with the product Cotek Battery Charger should be removed.

  • A new order line with the product Outback Power Remote Power System should be added.

Update Composition Request
PUT http://localhost:8080/rest
            /entities
            /sample_Order
            /288a5d75-f06f-d150-9b70-efee1272b96c
            ?responseFetchPlan=product-with-tags

{
  "customer": {
    "id": "f88597ff-009d-1cf2-4a90-a4fb5b08d835"
  },
  "date": "2021-03-01",
  "amount": 249.99,
  "lines": [
    {
      "id": "a1cd778b-fe49-4c74-05a0-6fb207dc11bd", (1)
      "product": {
        "id": "1860904a-5444-9c3e-9dc1-1d7a26d9ac19",
        "name": "Solar-One HUP Flooded Battery 48V"
      },
      "quantity": 3.0 (2)
    },
    { (3)
      "product": {
        "id": "f6884077-19c4-546f-33d4-a788399337f7",
        "name": "Outback Power Remote Power System"
      },
      "quantity": 1.0
    }
  ]
}
1 The ID of the existing order line is added to update the existing order line
2 The quantity value is set to 3.0 for the Solar-One HUP Flooded Battery 48V product
3 A new order line is added for the product Outback Power Remote Power System
When updating a child entity, like the order line in the example above, the ID of the existing order line needs to be added, so that Jmix recognizes it as an update. Otherwise, it would treat the child entity as a new entity.

The response to this update request contains the desired changes:

Response: 200 - OK
{
  "id": "288a5d75-f06f-d150-9b70-efee1272b96c",
  "date": "2021-03-01",
  "amount": 249.99,
  "lines": [
    {
      "id": "d0fdfaa8-7d65-5e25-49c2-d34fc41c0e55",
      "product": {
        "id": "1860904a-5444-9c3e-9dc1-1d7a26d9ac19",
        "name": "Solar-One HUP Flooded Battery 48V"
      },
      "quantity": 3.0, (1)
      "version": 2 (2)
    },
    {
      "id": "96722466-5164-a48c-b7f6-8d4c1bd605dd",
      "product": {
        "id": "f6884077-19c4-546f-33d4-a788399337f7",
        "name": "Outback Power Remote Power System" (3)
      },
      "quantity": 1.0
    }
  ],
  "version": 2,
  "customer": {
    "id": "f88597ff-009d-1cf2-4a90-a4fb5b08d835",
    "name": "Randall Bishop 3"
  }
}
1 The quantity has been updated for Solar-One HUP Flooded Battery 48V.
2 The version attribute was increased to indicate the update.
3 The new order line for Outback Power Remote Power System has been added to the order.

With this response, the order lines of the Order have been successfully updated.

When a child entity should not be updated, but still be kept in the composition, the ID of the existing order line needs to be part of the request nevertheless. This way Jmix recognizes it as still being part of the composition and does not delete it. Not putting that ID into the request would lead to Jmix deleting the entity (as this is how @Composition is handled), which might be considered accidental behavior, but is behaving as designed.

In the example from above when the order line for Cotek Battery Charger (55b925e5-9f3a-a725-9eb3-1240f9c1fe9) should not be changed at all, in the update it still needs to be listed with its ID:

Update Composition Request containing non-changing child entities
{
  "lines": [
    {
      "id": "55b925e5-9f3a-a725-9eb3-1240f9c1fe9" (1)
    },
    {
      "id": "a1cd778b-fe49-4c74-05a0-6fb207dc11bd",
      "product": {
        "id": "1860904a-5444-9c3e-9dc1-1d7a26d9ac19",
        "name": "Solar-One HUP Flooded Battery 48V"
      },
      "quantity": 3.0
    },
    {
      "product": {
        "id": "f6884077-19c4-546f-33d4-a788399337f7",
        "name": "Outback Power Remote Power System"
      },
      "quantity": 1.0
    }
  ]
}
1 Child entities that are not changed (like Cotek Battery Charger) but should still be part of the composition are referenced through its id.

Security Constraints for Association/Composition

As we learned above, the Update Entity endpoint will replace the existing association/composition collection with what is part of the request. For every entity reference that is not part of the request, the reference will be removed. Moreover, the entity that has been referenced before will be deleted from the application as well.

Having that in mind, let’s see how this situation behaves when Jmix Row-level Security is active for an entity:

Assuming you load an Order instance together with the nested collection of OrderLine instances.

There are security constraints that filter out some OrderLine instances, so you don’t load them and don’t know they exist. Say line5 is not loaded by the client but exists in the database. If you update the Order and remove line2 from the order lines, there are two outcomes:

  • If the constraints have not been changed since you loaded the entities, the framework restores the filtered line5 instance in the collection and deletes only line2, which is the correct behavior.

  • If the constraints have been changed in a way that line5 is now available to you, the framework cannot restore the information about filtered collection elements correctly. As a result, both line2 and line5 will be deleted.

You can eliminate possible data loss by sending a special system attribute in the JSON representing your entities. This attribute is called __securityToken and automatically included in resulting JSON if the jmix.core.entitySerializationTokenRequired application property is set to true.

Once you receive this __securityToken as part of the load response of the Entity, you can pass the value on to the Update Entity request. Here is an example of entity JSON including security token:

Request with Security Token
{
  "id": "fa430b56-ceb2-150f-6a85-12c691908bd1",
  "lines": [
    {
      "id": "82e6e6d2-be97-c81c-c58d-5e2760ae095a",
      "description": "Item 1"
    },
    {
      "id": "988a8cb5-d61a-e493-c401-f717dd9a2d66",
      "description": "Item 2"
    }
  ],
  "__securityToken": "0NXc6bQh+vZuXE4Fsk4mJX4QnhS3lOBfxzUniltchpxPfi1rZ5htEmekfV60sbEuWUykbDoY+rCxdhzORaYQNQ==" (1)
}
1 The Security Token is the value that has been previously received by the Load Entities API.

The __securityToken attribute contains encoded identifiers of filtered instances, so the framework can always restore the required information regardless of changes in constraints.

Partial Updates

It is possible to only send in the attributes that should be changed. In this case, all other attributes of the entity will stay untouched.

In the example below, you can send in an updated order date of the Order entity. Although the Order entity contains more attributes like customer, amount, lines.

Partial Order Update Request
PUT http://localhost:8080
         /entities
         /sample_Order
         /5a8adc2f-f4ef-17a9-9f97-1e715b3ade3d

{
  "date": "2020-12-06"
}
Response: 200 - OK
{
  "id": "5a8adc2f-f4ef-17a9-9f97-1e715b3ade3d",
  "date": "2020-12-06", (1)
  "amount": 130.08, (2)
  "version": 2 (3)
}
1 The date attribute was updated to the new order date.
2 Other attributes of the entity stay untouched.
3 The version attribute of the Order entity was increased to indicate the update.

Bulk Update

The Update-Entity API also allows you to update multiple entities within one request. For this, the JSON request body should contain an array of JSON objects representing each entity.

Bulk Update Request
PUT http://localhost:8080/rest
            /entities
            /sample_Customer

[
  {
    "name": "Randall Bishop 2"
  },
  {
    "name": "Sarah Doogle 2"
  }
]
Response: 200 - OK
[
  {
    "_entityName": "sample_Customer",
    "_instanceName": "Randall Bishop 2",
    "id": "833a610b-bc2c-2f44-c67a-2cf8b25f3291"
  },
  {
    "_entityName": "sample_Customer",
    "_instanceName": "Sarah Doogle 2",
    "id": "c8ab5ae2-7f8f-bc68-fb58-6cfcf7b1d235"
  }
]

In case of a violation of an entity validation, the entities will not be created, and a corresponding Error message will be returned. See Entity Validation for further details.