iMx*_*iMx 7 php symfony doctrine-orm
我有一个实体用户,它实现了AdvancedUserInterface.该实体具有UserProperties类的字段属性,该属性被映射为对象类型.
我的实体:
class User implements AdvancedUserInterface, \Serializable {
<....>
/**
* @var UserProperties
*
* @ORM\Column(name="properties", type="object", nullable=true, options={"default":null})
*/
private $properties;
<....>
}
Run Code Online (Sandbox Code Playgroud)
属性类:
class UserProperties {
public $isEmailVisible = false;
public $isNameVisible = false;
}
Run Code Online (Sandbox Code Playgroud)
如果数据库中的属性值为null,并且我对设置属性的实体对象进行了一些更改 - 它工作正常.但是,如果我对数据库进行了一些更改并且属性字段为非null(已存在序列化的UserProperties对象) - 则不会保存更改(但是用户实体上的所有其他更改都是).
我做错了什么?
跟踪策略的Doctrine检查对象是否已更改,在您的案例User类中.但是,当检查是否$this->properties已更改所有Doctrine时,检查它是否仍然指向内存中的同一对象(!).
如果要强制它更新存储对象,可以将其所有属性复制到新对象实例(new UserProperties然后重新分配给它$this->properties),克隆它,或将Doctrine跟踪策略更改为NOTIFY(请参阅http:// doctrine-orm. readthedocs.org/projects/doctrine-orm/en/latest/reference/change-tracking-policies.html).
然而,最后一个将要求您更改对象的所有setter并实际实现通知机制(如Doctrine docs中所示),所以当我的代码中弹出此问题时,我只是重新创建了存储的对象(这是我的第一个建议,如这很简单).
但我确实认为这是一种意想不到的行为,因此我会在Doctrine问题跟踪器中打开一个票据/问题,因此至少有一个文档会对此发出警告.
小智 6
这里的问题是Doctrine不检查序列化对象的值是否已经改变,它只检查对象是否是同一个(相同的内存指针).
如果您在Doctrine中使用对象序列化器,则需要始终创建对象的新实例以进行保存.
即
$user = $form->getData();
$properties = new UserProperties();
$properties->setProperty1($oldValue1);
$properties->setProperty2($newValue2);
...
$user->setProperties($properties);
$em->persist($properties);
$em->flush();
Run Code Online (Sandbox Code Playgroud)
当然,您应该能够创建对象的副本并仅分配更改的值.
$properties = clone $user->getProperties();
$properties->setProperty1($newValue);
$em->persist($properties);
$em->flush();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1890 次 |
| 最近记录: |