我有一个导入脚本,它读取XML文件并将数据添加到MySQL数据库。 xml文件包含Match-Data和相关事件。
我有以下实体
我的问题的相关关系:
内部匹配列表(反面)
/**
* @OneToMany(targetEntity="MatchEvent", mappedBy="match", orphanRemoval=true)
*/
private $events;
public function __construct($uId)
{
$this->setId($uId);
$this->events = new ArrayCollection();
}
Inside MatchEvent(拥有方)
/**
* @ManyToOne(targetEntity="MatchList", inversedBy="events")
* @JoinColumn(name="match_id", referencedColumnName="id")
*/
private $match;
在导入脚本中,每个匹配都有一个循环。在循环内部我想删除当前分配给该匹配的所有事件。在我想要将xml文件中的新事件添加到此匹配之后。
应该从数据库中完全删除事件。不仅是对比赛的引用。
简化示例
XML的内容
Match1
EventA
EventC
EventF
导入前
Match1
EventA
EventB
导入后应该是这样的
Match1
EventA
EventC
EventF
所以事件可能是
这是因为XML包含事件的更新或更正。 因此,唯一可靠的方法是删除所有已分配的事件,并添加最新xml中当前有效的事件。
我的问题是删除部分与立即添加一起。它自己的每项任务都在发挥作用。
我尝试了不同的方法(也阅读了学说文档),但我无法让它发挥作用。
遵循脚本的相关部分,我尝试了一些变体(注释掉) (不是整个代码。看看“......”我希望这足以理解我的问题/错误)
try
{
foreach($matches as $matchNode)
{
$match = new \MatchList($matchNode['uID']);
...
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$match->removeEvent($previousEvent);
//$previousEvent->setMatch(null);
//$this->em->remove($previousEvent);
//$this->em->persist($previousEvent);
}
foreach($teamData->Goal as $goal)
{
...
$event = new \MatchEvent($match);
$event->setPlayer($player);
$event->setType($goal['Type']);
$event->setPeriod($goal['Period']);
$this->em->persist($event);
$match->addEvent($event);
}
...
$this->em->persist($match);
}
$this->em->flush();
}
catch(Exception $e){}
无论我尝试过什么,它都没有按预期工作。有时我会收到错误(缺少级联持续存在)或没有错误发生但也没有删除。只有当我一次完成一项任务(删除或添加)时才有效。
我知道仅对反面进行的更改不会通过doctrine保存,因此我尝试在MatchEvent实体上调用remove。或者尝试取消设置整个ArrayCollection,并使用orphanRemoval也删除实体。
我一直在努力。 我希望有人可以帮助我理解我做错了什么,以及正确的方法。
谢谢
修改
添加我尝试过的每个变体都可能会有所帮助。
变体1)
之后不添加实体:从DB(GOOD)中删除事件
在下面添加实体:错误:通过关系'MatchList#events'找到一个新实体,该关系未配置为级联实体的持久化操作:MatchEvent @ XYZ。 (BAD)
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$this->em->remove($previousEvent);
}
变体2)
之后不添加实体:从DB(GOOD)中删除事件
在下面添加实体:错误:通过关系'MatchList#events'找到一个新实体,该关系未配置为级联实体的持久化操作:MatchEvent @ XYZ。 (BAD)
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->remove($previousEvent);
$this->em->detach($previousEvent);
}
变体3)
之后没有添加实体:错误:通过关系'MatchList#events'找到了一个新实体,该关系未配置为级联实体的持久化操作:MatchEvent @ XYZ。 (BAD)
立即添加实体:未尝试,因为甚至删除都没有效果。
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->detach($previousEvent);
}
变体4)
之后不添加实体:DB中的数据加倍,因为没有删除任何事件,所有事件附加插入match_id NULL。 (BAD)
立即添加实体:未尝试,因为甚至删除都没有效果。
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->detach($previousEvent);
$this->em->persist($previousEvent);
}
答案 0 :(得分:2)
我找到了解决方案。
对于此解决方案,添加“orphanRemoval = true”非常重要。
/**
* @OneToMany(targetEntity="MatchEvent", mappedBy="match", orphanRemoval=true)
*/
private $events;
在循环中,我使用removeElement从ArrayCollection中删除每个实体。因为orphanRemoval为true,所以实体也会被删除。
foreach($match->getEvents() as $event)
{
$match->getEvents()->removeElement($event);
}
添加实体与上面显示的相同。
我希望这个解释可以帮助其他人解决同样的问题。