18 votes

savoir quand appeler pour persister

J'utilise Doctrine 2 comme ORM, et les choses se passent bien, mais je m'interroge sur l'utilisation de l'ORM. EntityManager#persist() méthode. Le site "Entités persistantes" indique ce qui suit à propos d'un appel à persist() pour l'objet X :

Si X est une entité gérée préexistante, elle est ignorée par l'opération persist.

Cela me pousse à croire que persist() ne doit être appelé que lorsque l'objet est nouveau et n'a pas encore été enregistré dans la base de données. Cependant, la documentation de la méthode Politique de suivi des changements "Explicite différée". dit :

... Doctrine 2 ne prend en compte que les entités qui ont été explicitement marquées pour la détection des changements par un appel à EntityManager#persist(entity) ...

... qui ressemble à persist() doit être appelé sur l'objet pour qu'il soit mis à jour. Quand doit-on persist() être appelé ? Si ce n'est que pour les nouveaux objets, y a-t-il un impact significatif sur les performances si on l'appelle quand même chaque fois qu'une entité est mise à jour et qu'on laisse Doctrine faire la différence ?

19voto

arnaud576875 Points 35281

Avec le Différé Politique explicite (ce n'est pas la politique par défaut), vous devez appeler explicitement persist() sur chaque entité modifiée pour que doctrine les fasse persister. (Sauf pour les associations cascade-persist).

Doctrine doit toujours comparer la nouvelle valeur de chaque propriété avec la valeur originale pour savoir quelle propriété mettre à jour, ce qui peut avoir un impact sur la performance si vous persist() trop d'entités.

Avec le politique de suivi des changements par défaut vous devez seulement appeler persist sur les entités qui ne sont pas encore gérées par Doctrine (entités que vous avez créées avec new ). Avec cette politique, lorsque vous appelez flush(), la doctrine détecte automatiquement les entités qui ont été mises à jour et qui doivent être persistées.

7voto

Tgr Points 11766

La documentation est quelque peu trompeuse. En mode de suivi implicite, toutes les entités ont un état (géré, retiré, détaché, etc.) ; les entités obtenues par find() et des méthodes similaires (en fait, tout ce qui n'est pas créé avec le logiciel new ) sont déjà en état de gestion. Sur flush() toutes les entités gérées (et supprimées) sont vérifiées pour les changements et, si nécessaire, mises à jour dans la base de données.

En mode de suivi explicite, il y a une liste de contrôle supplémentaire pour la saleté, et persist() ajoute l'objet (et éventuellement les objets associés, selon les paramètres de la cascade) à cette liste. Seuls les objets de la liste de contrôle sale sont pris en compte pour la mise à jour. La liste de contrôle sale est effacée après le vidage, donc si vous effectuez un second vidage, et modifiez le même objet à nouveau, vous devez appeler la commande persist() une fois de plus. (En revanche, l'état géré est conservé après le flush).

Vous pouvez vérifier les détails par vous-même dans le Doctrine \ORM\UnitOfWork classe ; recherchez isChangeTrackingDeferredImplicit / isChangeTrackingDeferredExplicit (ce sont les seuls endroits où le comportement diffère selon les deux politiques).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X