[Symfony][Doctrine] Batch Processing - Bulk inserts with ManyToOne relation = ERROR: A new entity was found through the relationship
[Symfony][Doctrine] Batch Processing - Bulk inserts with ManyToOne relation = ERROR: A new entity was found through the relationship
我有 2 个具有 ManyToOne 关系的实体:Playlist 和 PlaylistVideo。一个播放列表可以有多个视频。 PlaylistVideo 属于 Playlist。播放列表已存在于数据库中。
我正在尝试使用批量插入,但我得到:
A new entity was found through the relationship 'App\Entity\Playlist\PlaylistVideo#playlist' that was not configured to cascade persist operations for entity: App\Entity\Playlist\Playlist__1.
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
播放列表实体:
class Playlist
{
/**
* @ORM\OneToMany(targetEntity=PlaylistVideo::class, mappedBy="playlist")
* @Groups({"playlist"})
*/
private Collection $videos;
...
public function addVideo(PlaylistVideo $video): self
{
if (!$this->videos->contains($video)) {
$this->videos[] = $video;
$video->setPlaylist($this);
}
return $this;
}
播放列表视频实体:
class PlaylistVideo
{
/**
* @ORM\ManyToOne(targetEntity=Playlist::class, inversedBy="videos")
* @ORM\JoinColumn(nullable=false)
*/
private Playlist $playlist;
...
public function setPlaylist(Playlist $playlist): self
{
$this->playlist = $playlist;
return $this;
}
批处理 - 批量插入:
/**
* Batch Processing - Bulk Inserts
* @param VideoDto[] $videos
*/
public function bulkInserts(Playlist $playlist, array $videos)
{
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
$videosAmount = count($videos);
$batchSize = 50;
for ($i = 0; $i < $videosAmount; $i++) {
$video = $videos[$i];
$playlistVideo = (new PlaylistVideo())
->setPlaylist($playlist)
->setVideoId($video->id)
->setTitle($video->title);
$this->em->persist($playlistVideo);
if (($i % $batchSize) === 0) {
$this->em->flush();
$this->em->clear();
}
}
$this->em->flush();
$this->em->clear();
}
我无法添加 cascade={"persist"}
(在 PlaylistVideo @ORM\ManyToOne()
中),因为我不想最终得到很多播放列表。
我已经尝试了所有方法,但我不能只将视频添加到播放列表。
你调用 $this->em->clear();并在其后使用相同的播放列表实体。 EntityManager 不再知道它了。您需要重新加载它。
for ($i = 0; $i < $videosAmount; $i++) {
$video = $videos[$i];
$playlistVideo = (new PlaylistVideo())
->setPlaylist($playlist)
->setVideoId($video->id)
->setTitle($video->title);
$this->em->persist($playlistVideo);
if (($i % $batchSize) === 0) {
$this->em->flush();
$this->em->clear();
// Reload the Playlist entity after clearing the EntityManager
$playlist = $this->em->getRepository(Playlist::class)->find($playlist->getId());
}
}
我有 2 个具有 ManyToOne 关系的实体:Playlist 和 PlaylistVideo。一个播放列表可以有多个视频。 PlaylistVideo 属于 Playlist。播放列表已存在于数据库中。
我正在尝试使用批量插入,但我得到:
A new entity was found through the relationship 'App\Entity\Playlist\PlaylistVideo#playlist' that was not configured to cascade persist operations for entity: App\Entity\Playlist\Playlist__1.
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
播放列表实体:
class Playlist
{
/**
* @ORM\OneToMany(targetEntity=PlaylistVideo::class, mappedBy="playlist")
* @Groups({"playlist"})
*/
private Collection $videos;
...
public function addVideo(PlaylistVideo $video): self
{
if (!$this->videos->contains($video)) {
$this->videos[] = $video;
$video->setPlaylist($this);
}
return $this;
}
播放列表视频实体:
class PlaylistVideo
{
/**
* @ORM\ManyToOne(targetEntity=Playlist::class, inversedBy="videos")
* @ORM\JoinColumn(nullable=false)
*/
private Playlist $playlist;
...
public function setPlaylist(Playlist $playlist): self
{
$this->playlist = $playlist;
return $this;
}
批处理 - 批量插入:
/**
* Batch Processing - Bulk Inserts
* @param VideoDto[] $videos
*/
public function bulkInserts(Playlist $playlist, array $videos)
{
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
$videosAmount = count($videos);
$batchSize = 50;
for ($i = 0; $i < $videosAmount; $i++) {
$video = $videos[$i];
$playlistVideo = (new PlaylistVideo())
->setPlaylist($playlist)
->setVideoId($video->id)
->setTitle($video->title);
$this->em->persist($playlistVideo);
if (($i % $batchSize) === 0) {
$this->em->flush();
$this->em->clear();
}
}
$this->em->flush();
$this->em->clear();
}
我无法添加 cascade={"persist"}
(在 PlaylistVideo @ORM\ManyToOne()
中),因为我不想最终得到很多播放列表。
我已经尝试了所有方法,但我不能只将视频添加到播放列表。
你调用 $this->em->clear();并在其后使用相同的播放列表实体。 EntityManager 不再知道它了。您需要重新加载它。
for ($i = 0; $i < $videosAmount; $i++) {
$video = $videos[$i];
$playlistVideo = (new PlaylistVideo())
->setPlaylist($playlist)
->setVideoId($video->id)
->setTitle($video->title);
$this->em->persist($playlistVideo);
if (($i % $batchSize) === 0) {
$this->em->flush();
$this->em->clear();
// Reload the Playlist entity after clearing the EntityManager
$playlist = $this->em->getRepository(Playlist::class)->find($playlist->getId());
}
}