зная, когда звонить сохраняться - PullRequest
11 голосов
/ 01 сентября 2011

Я использую Doctrine 2 в качестве своего ORM, и дела идут хорошо, но меня интересует метод EntityManager#persist().Документация "Сохраняющиеся сущности" гласит следующее о вызове persist() для объекта X:

Если X - это уже существующий управляемый объект, он игнорируетсяоперация persist.

Это наводит меня на мысль, что persist() нужно вызывать только тогда, когда объект новый и еще не сохранен в базе данных.Однако документация для политики отслеживания изменений «Отложенный явный» гласит:

... Doctrine 2 рассматривает только объекты, которые были явно помечены для обнаружения изменений посредством вызоваEntityManager # persist (entity) ...

... который звучит как persist(), должен быть вызван для объекта, чтобы он вообще обновлялся.Когда следует звонить persist()?Если только для новых объектов, будет ли значительный удар по производительности, чтобы вызывать его в любом случае, когда сущность обновляется и позволяет Doctrine разобраться в разнице?

Ответы [ 2 ]

11 голосов
/ 01 сентября 2011

С Отложенной явной политикой (это не политика по умолчанию), вам нужно явно вызывать persist () для каждого измененного объекта, чтобы доктрина сохраняла их.(За исключением каскадно-персистентных ассоциаций.)

Доктрине по-прежнему необходимо сравнивать новое значение каждого свойства с исходным значением, чтобы узнать, какое свойство обновлять, поэтому это может привести к снижению производительности, если вы тоже persist()много сущностей.

С политикой отслеживания изменений по умолчанию вам нужно вызывать постоянный вызов только для сущностей, которые еще не управляются Doctrine (сущности, которые вы создали с помощью new).С помощью этой политики при вызове flush () doctrine автоматически определяет, какие сущности были обновлены и должны быть сохранены.

6 голосов
/ 07 июня 2012

Документация несколько вводит в заблуждение. В режиме неявного отслеживания все объекты имеют состояние (управляемое, удаленное, отключенное и т. Д.); объекты, полученные с помощью find() и аналогичными методами (в основном все, что не создано с помощью new), уже находятся в управляемом состоянии. На flush() все управляемые (и удаленные) объекты проверяются на наличие изменений и, при необходимости, обновляются в БД.

В режиме явного отслеживания имеется дополнительный грязный контрольный список, и persist() добавляет объект (и, возможно, связанные объекты, в зависимости от настроек каскада) в этот список. Только элементы в грязном контрольном списке рассматриваются для обновления. Грязный контрольный список очищается после очистки, поэтому, если вы выполните вторую очистку и снова измените тот же объект, вы должны вызвать persist() еще раз. (Напротив, управляемое состояние сохраняется после сброса.)

Вы можете сами проверить детали в классе Doctrine \ ORM \ UnitOfWork ; найдите isChangeTrackingDeferredImplicit / isChangeTrackingDeferredExplicit (это единственные места, где поведение отличается в зависимости от двух политик).

...