我有阵列的类型字段中学说实体:
/**
* @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只是存储阵列领域?
指导思想是用相同的运算符(===)比较新旧值之间变化。 相同的对象(或对象的阵列)与不同的数据上使用的操作者始终返回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只是存储阵列领域?
你不能设置跟踪政策只是为了一个字段。
我解决了这个问题对我的代码的方法是使用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();
它的代码几行,但没有克隆或任何其他种类的魔法。 只要告诉学说直接做一个该死的更新! 希望这可以帮助。
注:在我的情况是,这不是被设置$元素。 我没有设置所有的比赛在前面查询和学说只是没有看到它,所以拒绝更新的元素。