web-dev-qa-db-ja.com

entity_load()からエンティティを更新し、現在のエンティティを再ロードする方法は?

エンティティが既に読み込まれている場合、entity_load()は、エンティティを再読み込みするのではなく、メモリから取得します。理にかなっています。

しかし:既に読み込まれているエンティティを再読み込みする必要がある場合、別の関数で読み込まれてからデータベースでエンティティのデータが変更された(または変更された可能性がある)場合に、変更したバージョンが必要になりますか?

エンティティをリロードする方法に最も近いのは、entity_load()の4番目のパラメーターをtrueに設定してentity_load()を呼び出すことです。たとえば、entity_load( $entity_type, $entity_id, null, true );ですが、これは単にエンティティをリロードするだけではありません。

また、サーバーのキャッシュをリセットするようにも見えます。これにより、多くの望ましくない副作用が発生する可能性があります(たとえば、これをエンティティの保存プロセスのステップとして呼び出すと、エンティティのキ​​ャッシュが作成されることがわかります。フィールドデータが欠落しているフィールド、およびエンティティが保存されてもこの誤って作成されたキャッシュは持続するため、エンティティのフィールドが保存に失敗し、少なくともキャッシュがクリアされるまで空白のエンティティが保存されたように見えます)。グーグルで見ると、このパラメーターの設定は一般に悪い考えだと考えられているように見えます(私が見た投稿はその理由については特定されていませんが、私の経験は手掛かりを提供します)。

それで、すでにロードされているが、ロード後に変更されたと思われるエンティティを他の最小限の影響で再ロードするにはどうすればよいですか?

Drupal 7、およびコアベースの回答が最善ですが、 Entity API contrib module または他の堅牢なcontribモジュールを使用する回答は問題ありません。

entity_load_unchanged() もあります。これは、キャッシュ自体をリセットしますが、その特定のエンティティIDに対してのみです。

これは、$ entity-> originalとして、presaveおよびinsert/updateフックでデフォルトですでに使用可能です。

5
Berdir

簡単な答えは、resetCache()メソッド呼び出しの処理方法はコントローラー次第であるため、問題のエンティティに依存するということです(DrupalDefaultEntityControllerで提供されるデフォルトの実装をオーバーライドする場合)。

コアの場合、デフォルトのエンティティキャッシュはすべて、シングルトンであるコントローラーの$ entityCacheプロパティをリセットするため、「サーバーのキャッシュをリセットする」が何を意味するのかは不明です。この場合、このキャッシュは永続化されます。単一のリクエストの存続期間を通して。このキャッシュをデータベースに永続化しようとするモジュールを使用している場合、確実にさらに影響を与える可能性がありますが、Drupalコア自体は、entity_loadを呼び出して単一のリクエストの存続期間を超えて影響を与えないはずですreset = TRUE。Entity API contribモジュールによって提供されるEntityAPIControllerでも、エンティティキャッシュのコア動作をオーバーライドしません。

さらに、ここで何を達成しようとしているのかは不明です。コアのentityCacheはとにかく静的キャッシュのみを使用しているため、リクエストの実行中にエンティティが変更される可能性はほとんどありません。エンティティの保存中にキャッシュをクリアしようとしている理由もわかりません。コアおよびEntityAPIモジュールは、エンティティの保存中に常にキャッシュをクリアする必要があります。同時実行性の問題に対処しようとしている場合は、エンティティを更新するよりも、保存を呼び出す前にエンティティの状態を確認し、ロックフレームワークを使用して、保存中にエンティティへの他の更新が行われないようにする方が良いでしょう。保存中にキャッシュをクリアします。

1
Mikey P