原则2从实体更新


Doctrine 2 update from entity

是否可以用类似的方式更新实体:

$data       = new ATest();  // my entity
$data->id   = 1;            // id 1 already exists, I just want to update this row
$data->name = "ORM Tested"; // changed the name
$entityManager->persist($data);
$entityManager->flush();

这将插入和更改对象的id,而不是更新数据库中的现有行。

你应该调用merge而不是persist:

$data = new MyEntity();
$data->setId(123);
$data->setName('test');
$entityManager->merge($data);
$entityManager->flush();

我不得不使用

$entityManager->merge($data)

您还可以使用getReference根据标识符更新实体属性,而无需检索数据库状态。

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/advanced-configuration.html reference-proxies

这将建立一个简单的代理通过ID与实体一起工作,而不是实例化一个new Entity或显式地使用find()从数据库中获取实体,然后可以通过flush更新。

$data = $entityManager->getReference('ATest', $id);
$data->setName('ORM Tested');
$entityManager->flush();

这对于更新实体的OneToManyManyToMany关联特别有用。例:$case->addTest($data);

手动设置新实体的标识符通常是不好的做法,即使意图是更新实体。相反,通常最好让EntityManager或Entity构造函数建立适当的标识符,例如UUID。由于这个原因,Doctrine将默认生成带有标识符作为私有属性的实体,没有setter方法。

或者直接获取被管理实体,而不是一个空实体。

$data = $entityManager->getRepository('ATest')->findOne(1); // ATest is my entitity class
$data->name = "ORM Tested"; // just change the name
$entityManager->persist($data);
$entityManager->flush();

如果实体已经被管理,persist()将更新它,而不是插入一个新的。