所以,我有一个由学说监视的实体存在。
我还有另一种决定,这是教义所不予关注的。
存在实体具有属性 $ decisions ,其类型为ArrayCollection,并且包含0到n个 Decision 实体。
由于我没有存储ArrayCollection中包含的每个 Decision 对象,因此我将属性 $ decision 键入Doctrine Array,到目前为止一切正常。 / p>
我可以从数据库中获取整个 Presence 对象,它包含我添加到其中的每个 Decision 对象。
当我编辑 Presence 对象的ArrayCollection中存在的一个 Decision 对象时,例如:
foreach($Presence->getDecisions() as $decision) {
$decision->setMorning($value);
}
修改是在本地应用的,当我输入dump($Presence);
Presence {#2354 ▼
#id: 8
#decisions: ArrayCollection {#1409 ▼
-elements: array:6 [▼
0 => Decision {#1408 ▼
#token_id: "005867b2915438c03383bb831d87c26346c586d6ecd46b735c7a23b4fabb682a8ac34a90ea3d53cc55c2209deaa83337abeb2b98ded43967fcfb0f4d04d5ada6"
#date: DateTime @1531692000 {#1407 ▶}
#morning: -1
#afternoon: 0
}
1 => Decision {#1406 ▶}
2 => Decision {#1404 ▶}
3 => Decision {#1402 ▶}
4 => Decision {#1400 ▶}
5 => Decision {#1398 ▶}
]
}
#last_edit_date: DateTime @1532109183 {#2454 ▼
date: 2018-07-20 19:53:03.062940 Europe/Berlin (+02:00)
}
#user: User {#1393 ▶}
}
在此dump()
上,您可以看到属性#morning: -1
是setter调用的结果。
但是当我尝试使用$this->entityManager->flush();
刷新更改时,尚未修改ArrayCollection。
起初,我认为这是更改检测的问题,因此我在我的 Presence 实体上添加了一个#last_edit_date
DateTime字段。
有趣的是,刷新时此属性可以很好地更新。
由于某些原因,ArrayCollection似乎不会更新。
要在此处补充我的信息,请参见其他信息:
控制器中的完整方法
/**
* @Route(name="edit_decision", path="/edit-decision/{tokenDate}/{dayPart}/{newValue}")
*/
public function EditDecisionAction(Request $request)
{
$token = $request->get('tokenDate');
$dayPart = $request->get('dayPart');
$newValue = intval($request->get('newValue'));
$myPresence = $this->em->getRepository('AppBundle:Presence')->findOneBy([
'user' => $this->connectedUser
]);
/** @var ArrayCollection $decisionCollection */
$decisionCollection = $myPresence->getDecisions();
$found = FALSE;
/** @var Decision $decision */
foreach ($decisionCollection as $decision) {
if ($decision->getTokenId() == $token) {
$found = TRUE;
if ($dayPart === 'morning') {
$decision->setMorning($newValue);
}elseif ($dayPart === 'afternoon') {
$decision->setAfternoon($newValue);
}
break;
}
}
if (!$found) {
throw $this->createNotFoundException();
}
// I set a new Date to trigger a modification on the Presence Entity : It works
$myPresence->setLastEditDate(new \DateTime());
// Here is the dump that you can see above
dump($myPresence);
$this->em->flush();
try{
$this->em->flush();
return $this->json([
'status' => TRUE
]);
}catch (\Exception $exception) {
return $this->json([
'status' => FALSE
]);
}
}
包含ArrayCollection的属性:
/**
* Doctrine Type Array
*
* @ORM\Column(type="array", nullable=true)
*/
protected $decisions;
欢迎任何帮助甚至提示! 谢谢:)
由于这篇文章,我可能找到了解决方法:
How to force Doctrine to update array type fields?
问题来自存储我的对象所依据的学说数组类型:
Doctrine使用相同的运算符(===)比较新旧值之间的变化。在具有不同数据的同一对象(或对象数组)上使用的运算符始终返回true。解决此问题的另一种方法是,您可以克隆需要更改的对象。
Nope仍然不能持久保存对ArrayCollection的项目所做的更改。 尝试克隆:添加:删除旧的,我们将检查会发生什么。
答案 0 :(得分:0)
好的,所以我终于可以使用技巧了。
主要问题是教义更改对Array类型的检测行为。
如上所述,原则是:Array ===用于检查是否要进行更改的数组。 之所以有点奇怪,是因为当您从ArrayCollection中添加或删除一个元素时,对于Doctrine而言,该集合仍等效于先前状态。 应该有一种方法可以像Java中那样测试2个对象之间的等效性。equals可以消除这些歧义。
无论如何我要解决它:
我将收藏集存储到初始状态:
$decisionCollection = $myPresence->getDecisions();
我放置了二传手并相应地修改了我的收藏集:
foreach ($myPresence->getDecisions() as $key => $decision) {
if ($decision->getTokenId() == $token) {
if ($dayPart === 'morning') {
$decision->setMorning($newValue);
} elseif ($dayPart === 'afternoon') {
$decision->setAfternoon($newValue);
}
break;
}
}
然后是技巧:
$myPresence->unsetDecisions();
$this->em->flush();
我完全取消了我的收藏集($ this-> collection = NULL)并第一次刷新。
由于数组!== NULL,它将触发更新
然后,我将集合与包含集合对象的更新集合一起设置:
$myPresence->setDecisions($decisionCollection);
$myPresence->setLastEditDate(new \DateTime());
最后一次刷新以保留新更改。
感谢大家的时间和评论!