与 OneToMany 关联持久实体后外键保持为空
Foreign key stays empty after persisting entity with OneToMany association
给定以下两个实体类
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class Tree
{
/**
* @ORM\Id()
* @ORM\Column(type="guid")
* @ORM\GeneratedValue(strategy="UUID")
* @var string
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Apple", mappedBy="tree", cascade={"persist"})
* @var Collection
*/
private $apples;
public function __construct()
{
$this->setApples(new ArrayCollection());
}
public function toArray(): array
{
return [
'id' => $this->getId(),
];
}
public function getId(): string
{
return $this->id;
}
public function setId(string $id): void
{
$this->id = $id;
}
public function getApples(): Collection
{
return $this->apples;
}
public function setApples(Collection $apples): void
{
$this->apples = $apples;
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class Apple
{
/**
* @ORM\Id()
* @ORM\Column(type="guid")
* @ORM\GeneratedValue(strategy="UUID")
* @var string
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Tree", inversedBy="apples")
* @var Tree
*/
private $tree;
public function toArray(): array
{
return [
'id' => $this->getId(),
];
}
public function getId(): string
{
return $this->id;
}
public function setId(string $id): void
{
$this->id = $id;
}
public function getTree(): Tree
{
return $this->tree;
}
public function setTree(Tree $tree): void
{
$this->tree = $tree;
}
}
除了 apple.tree_id
可以为 null 之外,数据库模式看起来不错。在这种情况下这已经是一个问题了吗?
我正在坚持如下条目:
<?php
declare(strict_types = 1);
namespace App\Service;
use App\Entity\Apple;
use App\Entity\Tree;
use Doctrine\ORM\EntityManager;
class Gardener
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function plantTree(): array
{
$entityManager = $this->entityManager;
$tree = new Tree();
$blueApple = new Apple();
$redApple = new Apple();
$tree->getApples()->add($blueApple);
$tree->getApples()->add($redApple);
$entityManager->persist($tree);
$entityManager->flush();
return (array) $tree;
}
}
执行持久化和刷新时没有错误或警告。一棵树和两个苹果条目正在存储,但是 apple.tree_id
始终为空。
似乎我对实体 类 的配置有误,但不确定是什么。我也尝试添加一个 JoinColumn
注释 @ORM\JoinColumn(name="tree_id", referencedColumnName="id")
,但它没有任何区别。
我需要进行哪些更改才能正确设置 appe.tree_id
?
您缺少 *ToMany
端的加法器和去除器功能。
如果您使用 Symfony >4,则将 setApples
函数替换为:
public function addApple(Apple $apple): Tree
{
$this->apples->add($apple);
return $this;
}
public function removeApple(Apple $apple): Tree
{
$this->apples->removeElement($apple);
return $this;
}
如果您使用的是 Zend Framework 3,请将 setApples
函数替换为:
public function addApples(array $apples): Tree
{
foreach ($apples as $apple) {
if (! $this->apples->contains($apple) {
$this->apples->add($apple)
$apple->setTree($this);
}
}
return $this;
}
public function removeApples(array $apples): Tree
{
foreach ($apples as $apple) {
if($this->apples->contains($apple) {
$this->apples->remove($apple);
}
}
return $this;
}
阅读 Working with Association 文档,其中显示示例并解释如何向 'n' 更新。
给定以下两个实体类
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class Tree
{
/**
* @ORM\Id()
* @ORM\Column(type="guid")
* @ORM\GeneratedValue(strategy="UUID")
* @var string
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Apple", mappedBy="tree", cascade={"persist"})
* @var Collection
*/
private $apples;
public function __construct()
{
$this->setApples(new ArrayCollection());
}
public function toArray(): array
{
return [
'id' => $this->getId(),
];
}
public function getId(): string
{
return $this->id;
}
public function setId(string $id): void
{
$this->id = $id;
}
public function getApples(): Collection
{
return $this->apples;
}
public function setApples(Collection $apples): void
{
$this->apples = $apples;
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table()
*/
class Apple
{
/**
* @ORM\Id()
* @ORM\Column(type="guid")
* @ORM\GeneratedValue(strategy="UUID")
* @var string
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Tree", inversedBy="apples")
* @var Tree
*/
private $tree;
public function toArray(): array
{
return [
'id' => $this->getId(),
];
}
public function getId(): string
{
return $this->id;
}
public function setId(string $id): void
{
$this->id = $id;
}
public function getTree(): Tree
{
return $this->tree;
}
public function setTree(Tree $tree): void
{
$this->tree = $tree;
}
}
除了 apple.tree_id
可以为 null 之外,数据库模式看起来不错。在这种情况下这已经是一个问题了吗?
我正在坚持如下条目:
<?php
declare(strict_types = 1);
namespace App\Service;
use App\Entity\Apple;
use App\Entity\Tree;
use Doctrine\ORM\EntityManager;
class Gardener
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function plantTree(): array
{
$entityManager = $this->entityManager;
$tree = new Tree();
$blueApple = new Apple();
$redApple = new Apple();
$tree->getApples()->add($blueApple);
$tree->getApples()->add($redApple);
$entityManager->persist($tree);
$entityManager->flush();
return (array) $tree;
}
}
执行持久化和刷新时没有错误或警告。一棵树和两个苹果条目正在存储,但是 apple.tree_id
始终为空。
似乎我对实体 类 的配置有误,但不确定是什么。我也尝试添加一个 JoinColumn
注释 @ORM\JoinColumn(name="tree_id", referencedColumnName="id")
,但它没有任何区别。
我需要进行哪些更改才能正确设置 appe.tree_id
?
您缺少 *ToMany
端的加法器和去除器功能。
如果您使用 Symfony >4,则将 setApples
函数替换为:
public function addApple(Apple $apple): Tree
{
$this->apples->add($apple);
return $this;
}
public function removeApple(Apple $apple): Tree
{
$this->apples->removeElement($apple);
return $this;
}
如果您使用的是 Zend Framework 3,请将 setApples
函数替换为:
public function addApples(array $apples): Tree
{
foreach ($apples as $apple) {
if (! $this->apples->contains($apple) {
$this->apples->add($apple)
$apple->setTree($this);
}
}
return $this;
}
public function removeApples(array $apples): Tree
{
foreach ($apples as $apple) {
if($this->apples->contains($apple) {
$this->apples->remove($apple);
}
}
return $this;
}
阅读 Working with Association 文档,其中显示示例并解释如何向 'n' 更新。