symfony 3 学说不接受主键
Posted
技术标签:
【中文标题】symfony 3 学说不接受主键【英文标题】:symfony 3 doctrine does not accept primary key 【发布时间】:2017-05-15 21:06:58 【问题描述】:我是 Symfony 的新手,正在尝试设置实体和关系。即使我似乎正确地注释了主键。
运行时
php bin/控制台原则:schema:validate
我收到如下错误:
引用的列名“brandId”必须是目标实体类“AppBundle\Entity\Brands”上的主键列。
实体看起来像(仅相关部分):
谢谢
品牌
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="brands")
*/
class Brands
/**
* @ORM\Id
* @ORM\Column(type="smallint",length=3,unique=true,options="unsigned":true)
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $brandId;
/**
* one brands has many models
* @ORM\OneToMany(targetEntity="Models", mappedBy="brandId")
* @ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
*/
private $models;
public function __construct()
$this->models = new ArrayCollection();
型号:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\ModelsRepository")
* @ORM\Table(name="models")
*/
class Models
/**
* @ORM\Column(type="smallint",length=4,unique=true,options="unsigned":true)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $modelId;
/**
* @ORM\Column(type="string", length=25)
*/
private $model;
/**
* Many models for one brand
* @ORM\ManyToOne(targetEntity="Brands",inversedBy="models")
* @ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
*/
private $brandId;
【问题讨论】:
只需按照这里的示例:docs.doctrine-project.org/projects/doctrine-orm/en/latest/… 修复关系后,将 Model::brandId 更改为 Model::brand @Cerad。谢谢,但为什么我要包括 ::brand 这是品牌名称的字段(如福特、宝马等)?它当然不会推动(双关语)任何关系。 因为品牌是品牌对象。 brandId 只是唯一标识符。对于 Doctrine 2,请尝试根据对象而不是数据库列名来思考。 【参考方案1】:一个有效且干净的实体映射应该是这样的:
品牌.php
/**
* @ORM\Entity
* @ORM\Table(name="brands")
*/
class Brand
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* one brands has many models
*
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Model", mappedBy="brand")
*/
private $models;
public function __construct()
$this->models = new ArrayCollection();
模型.php
class Model
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @ORM\Column(type="string", length=25)
*/
private $name;
/**
* Many models for one brand
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Brand",inversedBy="models")
*/
private $brand;
为了干净和易于使用:
$brand->getId(); //get id of brand
$brand->getModels(); //get array of Model object, ArrayCollection
$model->getBrand()->getId(); // Get id of related brand of some model
$model->getBrand()->getName(); //get the name of other propery of related brand
【讨论】:
感谢@rafrsr 提供有关正确设置实体的所有好的指示。作为初学者,他们当然非常感激。尽管如此,这并没有解决我的问题,正如我上面所说,似乎有一些更改没有从缓存中清除并导致错误。我需要了解如何从头开始重新初始化所有实体。【参考方案2】:在您的 Brands
模型中,不应存在此注释。
* @ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
JoinColumn
仅适用于 ManyToOne
和 OneToOne
字段。这是因为在一对多关系中,表中不会有包含关系拥有(“一”)方数据的连接列。
JoinColumn
用于在“多”端定义一个列,用于标识“一”端的哪个记录拥有它,因此将其包含在Models
模型中是可以的。
【讨论】:
这是一个开始。现在清理模型实体。 @Cerad 我知道命名有点不对劲,但该实体中的关系定义是否错误?我认为 JoinColumn 注释将转换为“在模型中创建一个brandId 列,该列引用品牌中的brandId 列”。我一定是错过了什么。 @Don'tPanic,正如你所说,它应该可以工作。我相信那是另一回事。我已经更改了一些字段名称,虽然我确实刷新了缓存,但似乎仍有一些东西挂在那里。我需要回去并找到一种从头开始重新初始化实体的方法。【参考方案3】:已删除错误答案...
额外提示:实体类或更好的实例应该代表表的单个数据集。所以他们的名字应该是单数的;) 通过为主键列选择不带前缀的名称,您可以节省一些代码,因为 Doctrine 可以发挥它的魔力。 此外,如果您不为所有列添加前缀,则不应在其中一列中添加表名前缀。
【讨论】:
关闭但不完全。在 OneToMany 关系上有一个参考列是否有意义? docs.doctrine-project.org/projects/doctrine-orm/en/latest/… @funcOder。我很清楚该字段需要成为主键。如果你回到我的问题,问题是 Symfony 不接受指令。根据所谓的教义魔法,我有一些不那么讨人喜欢的替代形容词。 @func0der,对不起,为什么要加入brandId=modelId。这似乎没有意义。如果您要执行 mysql 查询,则类似于 INNER JOIN ON (brand.brandId = models.brandId) 是的,对不起。你说的对。反正。使用文档重新检查您的代码。我认为你正在使用'mappedBy' wronf。【参考方案4】:这一切都成为了 Doctrine 命名策略的问题,我并不知道。见this article for details
该策略被设置为默认值,而我正在尝试使 mysql 的下划线命名策略适应 PHP 的驼峰命名策略。这导致 Symfony 找不到主节点,从而导致错误。
一旦我了解了这一点,并根据我在这篇文章中收到的宝贵意见,我将实体重构如下:
谢谢大家。
品牌
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="brands")
*/
class Brands
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type="smallint",length=3,unique=true,options="unsigned":true)
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* one brands has many models
*
* @ORM\OneToMany(targetEntity="Models", mappedBy="brandId")
*/
private $models;
public function __construct()
$this->models = new ArrayCollection();
/**
* @ORM\Column(type="string", length=25)
*/
private $brand;
.......
型号
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\ModelsRepository")
* @ORM\Table(name="models")
*/
class Models
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type="smallint",length=4,unique=true,options="unsigned":true)
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=25)
*/
private $model;
/**
* Many models for one brand
* @ORM\ManyToOne(targetEntity="Brands",inversedBy="models")
* @ORM\JoinColumn(name="brand_id", referencedColumnName="id")
*/
private $brandId;
/**
* Many models for one segment
* @ORM\ManyToOne(targetEntity="Segments", inversedBy="models")
* @ORM\JoinColumn(name="segment_id", referencedColumnName="id")
*/
private $segmentId;
.....
【讨论】:
以上是关于symfony 3 学说不接受主键的主要内容,如果未能解决你的问题,请参考以下文章