Problem/Motivation

Consider the following situation, a node type "page" exists with 1 field, "field_text".

When using a workspace to create a new page (nid = 1) the following happens:
2 revisions are created in the node_revision table:

||nid||vid||revision_default||
|1|2|0|
|1|1|1|

In the node base table, the node is referenced with vid 1 and has a status of unpublished.
In the node__field_text an entry is made with entity_id = 1, and revision_id = 1.

When we publish the node using the Workspace Publisher, the following happens.
The node base table, and node field table point to vid = 2. The node__field_text however is not updated and still points to revision_id = 1.

This mismatch occurs because we are trying to save a revision as the default revision. So the base, data and revision tables are updated correctly. However, the dedicated tables are not updated correctly.

This is because of the following statement in Drupal\Core\Entity\Sql\SqlContentEntityStorage:

// When updating an existing revision, keep the existing records if the
// field values did not change.
if (!$entity->isNewRevision() && $original && !$this->hasFieldValueChanged($field_definition, $entity, $original)) {
   continue;
}

Here, the field value has not changed, and we are not creating a new revision. Thus the field tables are not updated correctly.

Proposed resolution

Add a property to ContentEntityBase which forces the update of the dedicated tables. The property can be set using a public method on the ContentEntityBase so that we can force the update of data tables from the WorkspacePublisher.

The changes in short are this:
- Added new property "forceStorageUpdate", with a setter and getter on the Drupal\Core\EntityContentEntityBase class.


  /**
   * Settings this property will force the storage to update on entity save.
   *
   * @var bool
   */
  protected $forceStorageUpdate = FALSE;

  /**
   * {@inheritdoc}
   */
  public function forceStorageUpdate() {
    return $this->forceStorageUpdate;
  }

  /**
   * {@inheritdoc}
   */
  public function enforceStorageUpdate($enforce = TRUE) {
    $this->forceStorageUpdate = $enforce;
    return $this;
  }

- Checked in the SqlContentStorage if the save to the dedicated tables was forced.

      // When updating an existing revision, keep the existing records if the
      // field values did not change.
      // If the entity is set to force storage update, proceed with updating.
      if (!$entity->forceStorageUpdate() && !$entity->isNewRevision() && $original && !$this->hasFieldValueChanged($field_definition, $entity, $original)) {
        continue;
      }

Issues to discuss

- Are we a fan of this approach or does it open Pandora's box?
- I think the location where the new property and methods are added, are open for discussion.
- This fix can be used outside of workspaces so perhaps the component is not correct.

Similar issue

https://www.drupal.org/project/drupal/issues/2859042
This is basically the same issue, but my approach is different

CommentFileSizeAuthor
#8 3152820-8.patch4.17 KBmheip
#3 3152820-3.patch3.38 KBmheip

Comments

mheip created an issue. See original summary.

mheip’s picture

Title: Workspace entity field data is not updated on publishing » Workspaces // Revision id in dedicated table not updated on publishing
mheip’s picture

StatusFileSize
new3.38 KB
mheip’s picture

Issue summary: View changes
mheip’s picture

Assigned: mheip » Unassigned
Status: Active » Needs review
mheip’s picture

Issue summary: View changes

Status: Needs review » Needs work

The last submitted patch, 3: 3152820-3.patch, failed testing. View results

mheip’s picture

StatusFileSize
new4.17 KB
mheip’s picture

Status: Needs work » Needs review

Patch 8 applied, I had forgotten to add the new property to the translation and clone functions.

matsbla’s picture

This is basically the same issue, but my approach is different

If it is the same issue it means this is a duplicate.

Maybe you should publish the alternative solution in the referred issue?
#2859042: Impossible to update an entity revision if the field value you are updating matches the default revision.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

amateescu’s picture

Status: Needs review » Closed (duplicate)

I agree with #10, marking this as a duplicate of #2859042: Impossible to update an entity revision if the field value you are updating matches the default revision.. @mheip thanks for commenting in that issue to let people know that the Workspace module is also affected. Like @matsbla, I also think you should post your patch in that issue as well.