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:
PUT http://localhost:8080/rest
/entities
/sample_Customer
/13f01f59-8e5f-4fd9-802b-66501d49ac99
{
name: "Updated Name"
}
{
"_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:
{
"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.
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.
|
{
"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 ReferencesTo remove a reference for |
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:
{
"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 productSolar-One HUP Flooded Battery 48V
should be increased to3.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.
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:
{
"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 In the example from above when the order line for Update Composition Request containing non-changing child entities
|
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 onlyline2
, 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, bothline2
andline5
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:
{
"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
.
PUT http://localhost:8080
/entities
/sample_Order
/5a8adc2f-f4ef-17a9-9f97-1e715b3ade3d
{
"date": "2020-12-06"
}
{
"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.
PUT http://localhost:8080/rest
/entities
/sample_Customer
[
{
"name": "Randall Bishop 2"
},
{
"name": "Sarah Doogle 2"
}
]
[
{
"_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.