Problem/Motivation
SqlContentEntityStorage::doSaveFieldItems() now assumes that entity id can be accessed via $entity->get($this->idKey)->value when updating entities. However this is not always the case.
Relevant diff from #2342699: SqlContentEntityStorage tries to update identity/serial values by default:
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 150a18d64b..7edc4f6307 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -824,10 +824,13 @@ protected function doSaveFieldItems(ContentEntityInterface $entity, array $names
if ($update) {
$default_revision = $entity->isDefaultRevision();
if ($default_revision) {
+ // Remove the ID from the record to enable updates on SQL variants
+ // that prevent updating serial columns, for example, mssql.
+ unset($record->{$this->idKey});
$this->database
->update($this->baseTable)
->fields((array) $record)
- ->condition($this->idKey, $record->{$this->idKey})
+ ->condition($this->idKey, $entity->get($this->idKey)->value)
->execute();
}
Proposed resolution
Remaining tasks
User interface changes
API changes
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | 3027574-2.patch | 1.03 KB | tuutti |
Comments
Comment #2
tuutti commentedComment #3
tstoecklerCan you explain how this can happen?
This patch doesn't really hurt, in fact I like the new code slightly better because it doesn't rely on
$entityfor that part. But would be interested to hear what @amateescu or someone else thinks.Comment #4
tuutti commentedOne example would be https://gist.github.com/tuutti/70160e09ad70659a7a19904c8f87f2b9 where we use
entity_referencefield as entity id (where the main property istarget_id), but in theory this should break with any field that uses something else thanvalueas the main property.Comment #5
amateescu commentedI was about to write that a custom entity type might not use a field type with a
valuecolumn/main property for its ID, but @tuutti beat me to it :)Since that is completely supported by Entity API, I think the patch in #2 looks great :)
Comment #6
berdir+1 on the fix, makes sense. entity_reference ID field is pretty crazy, but if you have a 1:1 relationship between entities, I guess that works ;)
This might get pushed back due to missing test coverage, for that we would need to add another test entity type like that example, the amount of test entity types that we already have makes me pretty sad ;)
Comment #7
alexpottAs this is a regression I've committed this with no test. I do think it is worth having a follow-up to add this test case (an id field where value is not the main property) to core.
Committed and pushed 819a788ebd to 8.7.x and 2ecc2ee700 to 8.6.x. Thanks!
Comment #9
alexpott