Problem/Motivation

The current approach of using a single entity type definition has some of the following issues:

Having an entity type definition persisted to the database, that for non-storage related tasks is never actually invoked, but may perhaps be invoked in the future depending on the needs of $subsystem doesn't seem ideal. Especially since there is no warning in ent-up or the status report based on mismatched keys that don't inform storage. Is it assumed that installed definitions become out of sync with code definitions?

Proposed resolution

Split entity type definitions into two distinct objects (or sections within the current object, with clear boundaries) responsible for:

  • Storage related keys:
    • These would be the only keys persisted into the EntityLastInstalledSchemaRepository.
    • All changes would explicitly require an update hook.
    • The "active" or installed version of the object would be the only version exposed by an API, would remove the decision from a consumer
  • Non-storage related keys:
    • These would not be persisted.
    • A cache rebuild would refresh the definition and associated features.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

Sam152 created an issue. See original summary.

hchonov’s picture

The DX of installing/updating keys on the entity definition isn't ideal if you aren't making schema changes. It feels a bit redundant to write an update hook to replace keys in a data structure you've just adjusted in an annotation.

While I understand the frustration, I also think that it is safer to always write an update. It is also easier to always have an update, event it has no effect instead of having to think about the use cases when an update is required and when not.

sam152’s picture

Under the proposed solution, you would only write an update for changes to the 'storage' plugin definition. This is similar DX to field definition/storages. The result would mean writing less update hooks, which is a positive thing IMO.

I don't think users have are any expectations that an update hook needs to be written when updating non-storage related keys. Not even core is following this standard. Here is an example of an annotation change committed with no associated update hook: #2669802: Add a content entity form which allows to set revisions . Now there is a discrepancy between the "installed" definition and the live definition.

Reconciling or catching these kinds of issues in code reviews seems pretty difficult.

On the flip-side, if this is the right approach for post 8.7 entity annotation changes...

I also think that it is safer to always write an update

Then something should test any definition changes are always reflected by update hooks and these should also bubble up to users in the form of warnings on the status page etc. I don't think anything does that right now.

sam152’s picture

Here is another example: #3054582: Add field ui to workspaces.

Should these annotation changes have an update hook?

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

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

alexpott’s picture

+1 to this. We hit this with field_encrypt - see #3153125: Cache issue persists after update to 8.x-2.0-alpha2

The current docs for for hook_entity_type_alter() feel very insufficient...

/**
 * Alter the entity type definitions.
 *
 * Modules may implement this hook to alter the information that defines an
 * entity type. All properties that are available in
 * \Drupal\Core\Entity\Annotation\EntityType and all the ones additionally
 * provided by modules can be altered here.
 *
 * Do not use this hook to add information to entity types, unless one of the
 * following is true:
 * - You are filling in default values.
 * - You need to dynamically add information only in certain circumstances.
 * - Your hook needs to run after hook_entity_type_build() implementations.
 * Use hook_entity_type_build() instead in all other cases.
 *
 * @param \Drupal\Core\Entity\EntityTypeInterface[] $entity_types
 *   An associative array of all entity type definitions, keyed by the entity
 *   type name. Passed by reference.
 *
 * @see \Drupal\Core\Entity\Entity
 * @see \Drupal\Core\Entity\EntityTypeInterface
 */
function hook_entity_type_alter(array &$entity_types) {
  /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
  // Set the controller class for nodes to an alternate implementation of the
  // Drupal\Core\Entity\EntityStorageInterface interface.
  $entity_types['node']->setStorageClass('Drupal\mymodule\MyCustomNodeStorage');
}

In 8.7.0 the

You need to dynamically add information only in certain circumstances.

changed quite drastically. There are now many situations where this does not work. I'm not sure even the example in the hook works now.

amateescu’s picture

I'm not sure even the example in the hook works now.

It doesn't, you need to update the last installed definition and set the new storage class there as well :/

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

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now 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.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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.