如何强制Doctrine更新数组类型字段?

Dar*_*ski 12 php arrays doctrine symfony doctrine-orm

我有一个带有数组类型字段的Doctrine实体:

/**
 * @ORM\Table()
 */
class MyEntity
{
    (...)

    /**
     * @var array $items
     * 
     * @ORM\Column( type="array" ) 
     */
    private $items;

    /**
     * @param SomeItem $item 
     */
    public function addItem(SomeItem $item)
    {
        $this->items[] = $item;
    }

    (...)
}
Run Code Online (Sandbox Code Playgroud)

如果我向数组添加元素,此代码正常工作:

$myEntityObject->addItems(new SomeItem()); 
$EntityManager->persist($myEntityObject);
$EntityManager->flush();
Run Code Online (Sandbox Code Playgroud)

$myEntityObject 使用正确的数据保存到数据库(数组已序列化,并在查询数据库时反序列化).

不幸的是,当我在不改变该数组大小的情况下更改数组中的一个对象时,如果我试图将更改保存到数据库,则Doctrine不会执行任何操作.

$items = $myEntityObject->getItems();
$items[0]->setSomething(123);
$myEntityObject->setItems($items);
$EntityManager->persist($myEntityObject);
$EntityManager->flush();
print_r($myEntityObject);
Run Code Online (Sandbox Code Playgroud)

虽然,print_r在该代码的最后一行显示更改的对象的数据,但是如果数组大小没有更改,则Doctrine不知道数组内的某些内容已更改.有没有办法强制Doctrine保存在该字段中所做的更改(或者轻轻地告知它该字段中需要保存的更改)?


只是在文档中找到了解决我的问题的方法:

http://docs.doctrine-project.org/en/latest/reference/change-tracking-policies.html

它需要对代码进行大量更改,但它可以正常工作.有人知道如何保留其他字段的默认跟踪策略,并仅将NotifyPropertyChanged用于存储数组的字段吗?

Vad*_*man 25

Doctrine使用相同的运算符(===)来比较旧值和新值之间的变化.在具有不同数据的同一对象(或对象数组)上使用的运算符始终返回true.还有另一种方法可以解决此问题,您可以克隆需要更改的对象.

$items = $myEntityObject->getItems();
$items[0] = clone $items[0];
$items[0]->setSomething(123);
$myEntityObject->setItems($items);

// ...
Run Code Online (Sandbox Code Playgroud)

或者更改setItems()方法(我们只需要克隆一个对象来保存整个数组)

public function setItems(array $items) 
{
    if (!empty($items) && $items === $this->items) {
        reset($items);
        $items[key($items)] = clone current($items);
    }
    $this->items = $items;
}
Run Code Online (Sandbox Code Playgroud)

关于第二个问题:

有人知道如何保留其他字段的默认跟踪策略,并仅将NotifyPropertyChanged用于存储数组的字段吗?

您无法仅针对一个字段设置跟踪策略.