Symfony3编辑实体:错误主键缺失值
我尝试为产品目录创建树结构。 一个目录可以有多个级别,并且级别可以包含多个产品。Symfony3编辑实体:错误主键缺失值
我设法救我的结构,数据库,但是当我想编辑它,我有这样的错误:
Error : Missing value for primary key catalogCode on AppBundle\Entity\CatalogLevel
at OutOfBoundsException ::missingPrimaryKeyValue ('AppBundle\Entity\CatalogLevel', 'catalogCode')
in vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php at line 125
当我做这在我的CatalogController:
$form = $this->createForm(CatalogTreeType::class, $catalog);
但是,只是在该行之前,我验证我是否正确地获得了自己的级别,看起来像是这样:
// Create an ArrayCollection of the current levels
$originalLevels = new ArrayCollection();
foreach ($catalog->getLevels() as $level) {
var_dump($level->getCatalogCode());
$originalLevels->add($level);
}
// returns
AppBundle\Controller\CatalogController.php:337:string 'TT-FTEST' (length=8)
AppBundle\Controller\CatalogController.php:337:string 'TT-FTEST' (length=8)
CatalogLevel
实体具有一个组合键:levelId + catalogCode。
考虑到主键catalogCode
不是空,我不明白这个错误...
目录实体
/**
* @ORM\Table(name="catalogue")
* @ORM\Entity(repositoryClass="AppBundle\Entity\CatalogRepository")
* @UniqueEntity(fields="code", message="Catalog code already exists")
*/
class Catalog
{
/**
* @ORM\Column(name="Catalogue_Code", type="string", length=15)
* @ORM\Id
* @Assert\NotBlank()
* @Assert\Length(max=15, maxMessage="The code is too long ({{ limit }} characters max)")
*/
private $code;
/**
* @ORM\OneToMany(targetEntity="CatalogLevel", mappedBy="catalog", cascade={"persist", "remove"})
* @Assert\Valid
*/
private $levels;
/**
* Constructor
*/
public function __construct()
{
$this->levels = new ArrayCollection();
}
/**
* Get levels
*
* @return ArrayCollection
*/
public function getLevels()
{
return $this->levels;
}
/**
* Add level
*
* @param \AppBundle\Entity\CatalogLevel $level
*
* @return Catalog
*/
public function addLevel(\AppBundle\Entity\CatalogLevel $level)
{
$level->setCatalogCode($this->getCode());
$level->setCatalog($this);
if (!$this->getLevels()->contains($level)) {
$this->levels->add($level);
}
return $this;
}
/**
* Remove level
*
* @param \AppBundle\Entity\CatalogLevel $level
*/
public function removeLevel(\AppBundle\Entity\CatalogLevel $level)
{
$this->levels->removeElement($level);
}
}
CatalogLevel实体
/**
* @ORM\Table(name="catalogue_niveau")
* @ORM\Entity(repositoryClass="AppBundle\Entity\CatalogLevelRepository")
*/
class CatalogLevel
{
/**
* @ORM\Column(name="Niveau_ID", type="string", length=15)
* @ORM\Id
*/
private $id;
/**
* @ORM\Column(name="Catalogue_Code", type="string", length=15)
* @ORM\Id
*/
private $catalogCode;
/**
* @ORM\ManyToOne(targetEntity="Catalog", inversedBy="levels")
* @ORM\JoinColumn(name="Catalogue_Code", referencedColumnName="Catalogue_Code")
*/
private $catalog;
/**
* Set id
*
* @param string $id
*
* @return CatalogLevel
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* Set catalogCode
*
* @param string $catalogCode
*
* @return CatalogLevel
*/
public function setCatalogCode($catalogCode)
{
$this->catalogCode = $catalogCode;
return $this;
}
/**
* Get catalogCode
*
* @return string
*/
public function getCatalogCode()
{
return $this->catalogCode;
}
}
我会喜欢e提醒你,当我显示预先填充的表单时,editAction发生了这个错误(它在addAction上工作得很好)。
感谢您的帮助!
我认为这是因为您在实体CatalogLevel中没有自动增加id。尝试将此代码添加至此代码:
@ORM\GeneratedValue(strategy="AUTO")
您在创建实体的方式上遇到了一些问题。您应该使用自动生成策略。此外,“@ORM \ Id”注释是唯一标识符。
此外,您的“JoinColumn”不正确。您需要回顾“目录”实体,它是id(标识符)。 CatalogLevel类中不需要2个“@ORM \ Id”条目。
所以进行这些更改:
/**
* @ORM\Table(name="catalog")
* @ORM\Entity(repositoryClass="AppBundle\Entity\CatalogRepository")
*/
class Catalog
{
/**
* @ORM\Column(name="cat_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $cat_id;
/**
* @ORM\OneToMany(targetEntity="CatalogLevel", mappedBy="catalog", cascade={"persist", "remove"})
* @Assert\Valid
*/
private $levels;
...
/**
* @ORM\Table(name="catalog_level")
* @ORM\Entity(repositoryClass="AppBundle\Entity\CatalogLevelRepository")
*/
class CatalogLevel
{
/**
* @ORM\Column(name="cat_level_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $cat_level_id;
/**
* @ORM\ManyToOne(targetEntity="Catalog", inversedBy="levels")
* @ORM\JoinColumn(name="local_cat_id", referencedColumnName="cat_id")
*/
private $catalog;
...
感谢您的回复,但我没有为Catalog和CatalogLevel使用自动增量ID。用户可以输入目录的代码,并将此代码用作主键。 为了具有唯一的级别标识符,我使用组合键与目录代码和级别ID,我在提交表单后(我在jquery中构建拖放树并在js中生成ids)后获得了该级别ID。 保存在数据库中效果很好。我的“catalogue_niveau”表中包含所有关卡数据。此外,我的错误发生在AbstractProxyFactory类上,而不是直接在Entity CatalogLevel上。 – Felurian
我在互联网上找到了一种避免此错误的方法:删除实体CatalogLevel中的$ catalogCode属性的@ORM \ Id。 编辑窗体正在显示,并预先填充了关卡数据。但我不认为这是一个可行的解决方案... – Felurian
感谢您的答复,但因为我创造我的树与jQuery和我修复表单数据IDS提交后,我不使用CatalogLevel自动增量ID。例如,关卡ID是这样的:item-1,item-2,item-xx。 保存在数据库中效果很好。我的“catalogue_niveau”表中包含所有关卡数据。此外,我的错误发生在AbstractProxyFactory类上,而不是直接在Entity CatalogLevel上。 – Felurian
好的,所以我不知道可能是什么原因造成的,但是有一种更简单的方法。你可以使用[doctrine tree extension](https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/tree.md#including-extension)。一张桌子上的所有魔法。 – ciurciurek
我不知道,谢谢!我会看看它是否与我的结构相符。 – Felurian