4

If an entity has already been loaded, entity_load() retrieves it from memory rather than reloading it. Makes sense.

But: what can you do when you need to reload an entity that has already been loaded - when the entity's data has (or, may have) been changed in the database since it was loaded by another function, and you need the changed version?

The closest I can find to a way to reload an entity is to call entity_load() with the 4th parameter of entity_load() to true - for example, entity_load( $entity_type, $entity_id, null, true ); - however, this does much more than just reload the entity.

It also appears to reset the cache on the server, which can have a lot of undesired side effects (for example, I'm finding that calling this as a step in the process of saving an entity causes a cache to be created for the entity's fields that is missing field data, and this faulty created cache persists even as the entity is saved, causing it to seem like the entity's fields failed to save and a blank entity was saved, at least until caches are cleared). From googling around, I get the impression that setting this parameter is generally considered to be A Bad Idea (posts I've seen aren't specific about why, but my experience offers a clue).

So, how can I re-load an entity that has already been loaded but which I suspect has been changed since being loaded, with minimal other consequences?

Drupal 7, and while core-based answers are best any answers that use the Entity API contrib module or other robust contrib modules are fine.

5

There is entity_load_unchanged(), which does a reset cache itself as well, but however only for that specificy entity id.

This is already available by default in presave and insert/update hooks as $entity->original.

  • :-) Perfect answer! So does accessing $entity->original reset the database fields cache entry for the entity too, or does it simply bypass the database cache, getting the data from the database while leaving the cache table alone? – user568458 Aug 9 '12 at 9:35
  • $entity->original is the return value of the mentioned function, so the caches have already been cleared. This has already happened, and happens no matter if you access it or not. So strictly speaking does accessing $entity->original not (again) clear the cache ;) – Berdir Aug 9 '12 at 18:29
1

The short answer is that it depends on the entity in question, as it's up to the controller how to handle the resetCache() method call (if it overrides the default implementation provided in DrupalDefaultEntityController).

It's unclear what you mean by "reset the cache on the server" since all the default entity cache does in the case of core, is reset the $entityCache property on the controller which is just a singleton, so in this case this cache only persists through the lifetime of a single request. If you are using modules that try to persist this cache to the database that could definitely have more implications, but Drupal core by itself should have no affects past the lifetime of a single request by calling entity_load with reset=TRUE. Even the EntityAPIController provided by the Entity API contrib module doesn't override the core behavior for entity caching.

Further, it's unclear what you are trying to accomplish here, the entityCache in core is only using a static cache anyway, so there is little chance of an entity changing during the duration of a request. I'm also unsure why you are trying to clear the cache while saving an entity, core and EntityAPI modules should always clear the cache while saving an entity. If you are trying to deal with concurrency issues, perhaps it would be better to check the state of the entity prior to invoking save, and then using the locking framework to prevent other updates to the entity while saving, rather than trying to update the entity and clear the cache while it is being saved.

  • The general case is, field data synchronisation functions using hook_field_insert that write fields to specific other entities in a cascading fashion. This can result in fresh fields being written onto the original entity - a concurrency that is unusual but legitimate in the business logic of the module. The entity is legitimately changing on the database during the cycle, and there's one specific point where the entity held in memory needs to be updated to reflect the current state of the entity on the database. Specifically, I need to load the fields stored on the database, for comparison. – user568458 Aug 8 '12 at 22:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.