如何强制学说更新数组类型的字段?(How to force Doctrine to update a

2019-06-25 14:11发布

我有阵列的类型字段中学说实体:

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

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

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

    (...)
}

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

$myEntityObject->addItems(new SomeItem()); 
$EntityManager->persist($myEntityObject);
$EntityManager->flush();

$myEntityObject被保存到与正确数据的数据库(数组被序列化和查询数据库时反序列化)。

不幸的是,当我改变内部数组对象的一个​​,而不改变该数组的大小,原则不做任何事情,如果我试图将更改保存到数据库中。

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

虽然, print_r在改变对象的数据代码显示的最后一行,原则不知道什么东西该数组内改变,如果数组的大小没有改变。 有没有什么办法,迫使学说保存在该领域所做的更改(或轻轻通知它在这一领域需要更改保存)?


就在文档找到一种方式来解决我的问题:

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

它需要大量的代码更改的,但它的作品。 是否有人知道如何保存默认跟踪政策等领域,并使用NotifyPropertyChanged只是存储阵列领域?

Answer 1:

指导思想是用相同的运算符(===)比较新旧值之间变化。 相同的对象(或对象的阵列)与不同的数据上使用的操作者始终返回true。 还有其他的方式来解决这个问题,你可以克隆需要改变的对象。

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

// ...

或改变setItems()方法(我们需要克隆只有一个对象将持续整个数组)

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

关于第二个问题:

是否有人知道如何保存默认跟踪政策等领域,并使用NotifyPropertyChanged只是存储阵列领域?

你不能设置跟踪政策只是为了一个字段。



Answer 2:

我解决了这个问题对我的代码的方法是使用createQueryBuilder,只是创建更新查询。 这样的学说没有说没办法了:)

所以我从这个去

$em          = $this->getDoctrine()->getManager();
$matchEntity = $em->getReference('MyBundleBundle:Match', $match_id);


$matchEntity->setElement($element);
$matchEntity->setTeamHomeColour($data['team_a_colour']);
$matchEntity->setTeamAwayColour($data['team_b_colour']);

为此:

$repository = $this->getDoctrine()->getRepository('MyBundleBundle:Match');
$query      = $repository->createQueryBuilder('u')
    ->update()
    ->set('u.element', ':element')
    ->set('u.teamHomeColour', ':thomecolour')
    ->set('u.teamAwayColour', ':tawaycolour')
    ->where('u.matchId = :match')

    ->setParameter('element', $element)
    ->setParameter('thomecolour', $data['team_a_colour'])
    ->setParameter('tawaycolour', $data['team_b_colour'])
    ->setParameter('match', $matchEntity)

    ->getQuery();

$query->execute();

它的代码几行,但没有克隆或任何其他种类的魔法。 只要告诉学说直接做一个该死的更新! 希望这可以帮助。

注:在我的情况是,这不是被设置$元素。 我没有设置所有的比赛在前面查询和学说只是没有看到它,所以拒绝更新的元素。



文章来源: How to force Doctrine to update array type fields?