知道何时呼叫坚持

Pro*_*tic 11 php doctrine-orm

我正在使用Doctrine 2作为我的ORM,事情进展顺利,但我一直在想这个EntityManager#persist()方法.在"坚持实体"文件说,要调用下面persist()的对象X:

如果X是预先存在的托管实体,则persist操作会忽略它.

这使我相信persist()只有当对象是新的并且尚未保存到数据库时才需要调用.但是,"Deferred Explicit"更改跟踪策略的文档说:

... Doctrine 2仅考虑通过调用EntityManager#persist(entity)明确标记用于更改检测的实体...

...听起来像persist()必须在对象上调用它才能进行更新.什么时候应该persist()叫?如果仅对新对象进行操作,那么无论何时更新实体并让Doctrine解决差异,是否存在重要的性能影响?

Arn*_*anc 11

使用Deferred Explicit策略(它不是默认策略),您需要在每个已修改的实体上显式调用persist()以使其继承.(级联持久关联除外.)

Doctrine仍需要将每个属性的新值与原始值进行比较,以了解要更新的属性,因此如果persist()实体太多,这可能会影响性能.

使用默认的更改跟踪策略,您只需要对尚未由Doctrine管理的实体(您创建的实体new)调用persist .使用此策略,当您调用flush()时,doctrine会自动检测哪些实体已更新并需要保留.

  • 过了一半的生活,直到问题被认为默认政策是延期明确的政策. (4认同)

Tgr*_*Tgr 6

文档有点误导.在隐式跟踪模式中,所有实体都具有状态(托管,删除,分离等); 通过find()类似方法获得的实体(基本上所有未创建的实体new)都已处于托管状态.打开flush(),检查所有托管(和删除)的entites是否有更改,如有必要,在DB中更新.

在显式跟踪模式下,还有一个额外的脏检查列表,persist()并将该对象(以及可能关联的对象,具体取决于级联设置)添加到该列表中.仅考虑脏检查列表中的项目进行更新.刷新后清除脏检查列表,因此如果再次刷新,并再次更改同一对象,则必须再次调用persist().(相反,管理状态在刷新后保留.)

您可以在Doctrine\ORM\UnitOfWork类中查看自己的详细信息; 搜索isChangeTrackingDeferredImplicit/ isChangeTrackingDeferredExplicit(这些是两个政策下行为不同的唯一地方).