对 ArrayCollection 项的更改已完成,但不会保留在数据库中



简介

因此,我有一个实体存在,受到条令的监视
我还有另一个实体决策没有受到条令的关注。

Presence实体有一个属性$Decision,类型为ArrayCollection,包含0到n个Decision实体。

由于我没有存储ArrayCollection中包含的每个Decision对象,因此我将属性

$Decision我可以从数据库取回整个Presence对象&它包含我添加到其中的每个Decision对象。

问题

当我编辑一个Decision对象时,该对象存在于我的Presence的ArrayCollection中,如:

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_dateDateTime字段
有趣的是,这个属性在刷新时更新得很好。

似乎由于某种原因,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
*
* @ORMColumn(type="array", nullable=true)
*/
protected $decisions;

欢迎任何帮助甚至提示!谢谢:(

更新2

由于这篇文章,我可能找到了解决方案:
如何强制Doctrine更新数组类型字段?

问题来自于我存储对象的阵列类型:

条令使用相同的运算符(===(来比较新旧值之间的变化。在具有不同数据的同一对象(或对象数组(上使用的运算符总是返回true。还有另一种方法可以解决这个问题,您可以克隆需要更改的对象。

更新3

No仍然不会持久化对数据库中ArrayCollection项所做的更改。尝试克隆:添加:删除旧的,我们将看看会发生什么。

最终更新

好吧,所以我终于用了一个技巧让它发挥作用。

主要问题是条令的行为改变了对阵列类型的检测。

如上所述,条令是这样做的:数组===数组检查是否有更改。有点奇怪,因为当你从ArrayCollection中添加或删除一个元素时,对于Doctrine来说,该集合仍然相当于先例状态。应该有一种方法来测试两个对象之间的等价性,比如在Java.equals中,以消除这些歧义。

不管怎样,我做了什么来解决它:
我将我的收藏存储到一个初始状态:

$decisionCollection = $myPresence->getDecisions();

我把我的setters&相应地修改我的收藏:

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->集合=NULL(&第一次冲洗
它触发更新自数组!==NULL
然后我用包含设置对象的更新集合设置我的集合:

$myPresence->setDecisions($decisionCollection);
$myPresence->setLastEditDate(new DateTime());

最后一次刷新以保持新的更改。

感谢大家抽出时间&您的评论!

最新更新