Problem/Motivation

Entity keys tell you how to get the common fields of different entity types that might have different specific field names. E.g. 'created', 'published', 'author'.

Entities which implement EntityChangedInterface are expected to have a field to store the changed timestamp, but there's no way to find out what that field is.

This affects code which needs to work at the field level rather than use the interface methods -- e.g. using JSONAPI data.

Steps to reproduce

Proposed resolution

Add a 'changed' entity key to core entity types which implement EntityChangedInterface.

  1. In the Drupal code base, lookup all content entity types that have EntityChangedInterface implemented.
  2. Per entity type, find out how the field is called that stores the changed timestamp.
  3. Define the new key in the annotation of the entity class, for example if the field is called "foo":
     *   entity_keys = {
    (...)
     *     "changed" = "foo",
     *   },
    

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3549707

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joachim created an issue. See original summary.

megachriz’s picture

Issue summary: View changes
Issue tags: +Vienna2025

The Drupal Contribution Mentoring team is triaging issues for DrupalCon Vienna 2025, and we are reserving this issue for Mentored Contribution during the event.

After October 17, this issue returns to being open to all. Thanks!

I also updated the issue summary with the list of steps to resolve the issue.

robbertnl’s picture

I am working on this #vienna2025 during mentored contribution with @megachriz

robbertnl’s picture

Status: Active » Needs work

I added the changed field to entity_keys but now the test pipeline is failing. This still needs to be fixed by someone.

joachim’s picture

Wow, that's some impressive test failures!

AFAIK nothing is looking for the 'changed' entity key, since, again AFAIK, we're inventing it in this MR. And yet, things fall over dramatically:

> ├ SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'changed' cannot be null: INSERT INTO "test36480953taxonomy_term_field_data" ("tid", "revision_id", "vid", "langcode", "status", "name", "description__value", "description__format", "weight", "changed", "default_langcode", "revision_translation_affected") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11); Array

joachim’s picture

I can't reproduce the test failure locally -- this gets in the way: #3552984: MigrateTestBase::display() causes a TypeError if a test fails a migration.

joachim’s picture

Issue tags: -Novice

Ok I can confirm that with the MR, the 'changed' field on taxonomy terms doesn't get an ALLOW NULL, and without the MR, it does.

I have NO idea how!!!

joachim’s picture

Found it:

    // A shared table contains rows for entities where the field is empty
    // (since other fields stored in the same table might not be empty), thus
    // the only columns that can be 'not null' are those for required
    // properties of required fields. For now, we only hardcode 'not null' to a
    // few "entity keys", in order to keep their indexes optimized.
    // @todo Fix this in https://www.drupal.org/node/2841291.
    $not_null_keys = $this->entityType->getKeys();
    // Label and the 'revision_translation_affected' fields are not necessarily
    // required.
    unset($not_null_keys['label'], $not_null_keys['revision_translation_affected']);
    // Because entity ID and revision ID are both serial fields in the base and
    // revision table respectively, the revision ID is not known yet, when
    // inserting data into the base table. Instead the revision ID in the base
    // table is updated after the data has been inserted into the revision
    // table. For this reason the revision ID field cannot be marked as NOT
    // NULL.
    if ($table_name == $base_table) {
      unset($not_null_keys['revision']);
    }

Urgghh. Spooky side-effects FTL :(

We probably need to add 'changed' to the keys that are unset here.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.