我有一个学说实体用户,它实现了高级用户的界面。该实体具有类用户properties的字段属性,该字段被映射为对象类型。
我的实体:
class User implements AdvancedUserInterface, Serializable {
<....>
/**
* @var UserProperties
*
* @ORMColumn(name="properties", type="object", nullable=true, options={"default":null})
*/
private $properties;
<....>
}
属性类:
class UserProperties {
public $isEmailVisible = false;
public $isNameVisible = false;
}
如果数据库中的属性值为 null ,并且我对设置属性的实体对象进行了一些更改 - 它工作正常。但是,如果我对数据库进行了一些更改,并且属性字段不是null(已经有一个序列化的用户properties对象),则不会保存更改(但是对用户实体上的所有其他更改均为)。
>我做错了什么?
跟踪学说的策略检查对象是否已更改,在您的情况下-User
类。但是,检查$this->properties
是否已更改时,所有学说的做法是检查它是否仍然指向内存中的同一对象(!)。
如果要强迫它更新存储的对象,则可以将所有属性复制到新的对象实例(new UserProperties
,然后将其重新分配给$this->properties
),克隆它,或将教义跟踪策略更改为NOTIFY
(请参阅教义文档)。
最后一个将要求您更改对象的所有设置并实际实现通知机制(如教义文档中所示),因此当我的代码中弹出此问题时,我刚刚重新创建了存储的对象(这是我的第一个建议,因为很简单)。
但是,我确实认为这是一种出乎意料的行为,所以我会在学说问题跟踪器中打开票/问题,因此至少要警告一下。
问题是,学说不检查序列化对象的值是否已更改,它仅检查对象是否是相同的(相同的内存指针)。
如果您正在使用学说中的对象序列化处理程序,则需要始终创建一个新实例以保存它。
即。
$user = $form->getData();
$properties = new UserProperties();
$properties->setProperty1($oldValue1);
$properties->setProperty2($newValue2);
...
$user->setProperties($properties);
$em->persist($properties);
$em->flush();
当然,您应该能够创建对象的副本并仅分配更改的值。
$properties = clone $user->getProperties();
$properties->setProperty1($newValue);
$em->persist($properties);
$em->flush();