复合标识符,但使用 ID 生成器而不是手动分配 + Symfony2

Posted

技术标签:

【中文标题】复合标识符,但使用 ID 生成器而不是手动分配 + Symfony2【英文标题】:composite identifier, but uses an ID generator other than manually assigning + Symfony2 【发布时间】:2014-03-18 18:01:53 【问题描述】:

我有三张桌子。

item 带字段

    PK id
    title
    description
    type
    created
    delete
    fk user_id

article 带字段

    PK item_id (one-to-one with item table), 
    body

media 带字段

    PK id
    FK item_id (many-to-one with item table)
    url
    type
    mimetype
    isexternal

article 表中的 type 字段是一个 ENUM,其值为 ITEM, ARTICLE and IMAGE。 实体是自动生成的。因此,最初的文章实体不扩展项目实体。我必须改变它。

我总是收到这个错误:

Entity 'Beachteam\BeachteamBundle\Entity\Article' has a composite identifier 
but uses an ID generator other than manually assigning (Identity, Sequence). 
This is not supported.

更新: 删除我的类型变量并修复 discriminatormap 后,我收到此错误:

Property Beachteam\BeachteamBundle\Entity\Item::$type does not exist

这是我更新的物品实体:

<?php

namespace Beachteam\BeachteamBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Item
 *
 * @ORM\Table(name="item", indexes=@ORM\Index(name="fk_item_user1_idx", columns="user_id"))
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap(
 *     "ITEM"="Beachteam\BeachteamBundle\Entity\Item",
 *     "ARTICLE"="Beachteam\BeachteamBundle\Entity\Article",
 *     "IMAGE"="Beachteam\BeachteamBundle\Entity\Media"
 * )
 */
class Item

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
     */
    private $title;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text", nullable=true)
     */
    private $description;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime", nullable=false)
     */
    private $created;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="deleted", type="datetime", nullable=true)
     */
    private $deleted;

    /**
     * @var \Beachteam\BeachteamBundle\Entity\User
     *
     * @ORM\ManyToOne(targetEntity="Beachteam\BeachteamBundle\Entity\User")
     * @ORM\JoinColumns(
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * )
     */
    private $user;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    
        return $this->id;
    

    /**
     * Set title
     *
     * @param string $title
     * @return Item
     */
    public function setTitle($title)
    
        $this->title = $title;

        return $this;
    

    /**
     * Get title
     *
     * @return string 
     */
    public function getTitle()
    
        return $this->title;
    

    /**
     * Set description
     *
     * @param string $description
     * @return Item
     */
    public function setDescription($description)
    
        $this->description = $description;

        return $this;
    

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription()
    
        return $this->description;
    

    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Item
     */
    public function setCreated($created)
    
        $this->created = $created;

        return $this;
    

    /**
     * Get created
     *
     * @return \DateTime 
     */
    public function getCreated()
    
        return $this->created;
    

    /**
     * Set deleted
     *
     * @param \DateTime $deleted
     * @return Item
     */
    public function setDeleted($deleted)
    
        $this->deleted = $deleted;

        return $this;
    

    /**
     * Get deleted
     *
     * @return \DateTime 
     */
    public function getDeleted()
    
        return $this->deleted;
    

    /**
     * Set user
     *
     * @param \Beachteam\BeachteamBundle\Entity\User $user
     * @return Item
     */
    public function setUser(User $user)
    
        $this->user = $user;

        return $this;
    

    /**
     * Get user
     *
     * @return \Beachteam\BeachteamBundle\Entity\User 
     */
    public function getUser()
    
        return $this->user;
    

这是我更新的文章实体:

<?php

namespace Beachteam\BeachteamBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Item
 *
 * @ORM\Table(name="article")
 * @ORM\Entity
 */
class Article extends Item

    /**
     * @var string
     *
     * @ORM\Column(name="body", type="text")
     */
    protected $body;

    /**
     * Set body
     *
     * @param string $body
     * @return Article
     */
    public function setBody($body)
    
        $this->body = $body;

        return $this;
    

    /**
     * Get body
     *
     * @return string 
     */
    public function getBody()
    
        return $this->body;
    

谁能解释一下这个错误(互联网对我没有多大帮助)。为什么我会收到这个错误?

P.S.:我使用的是 Symfony 2.4.1 和 PHP 5.4.20

【问题讨论】:

您使用的是什么数据库平台?这更像是 symfony 的教义 我正在使用 mysql 数据库。 【参考方案1】:

我认为这条线(Item):

/**
 * @ORM\DiscriminatorMap("ITEM"="Item", "ARTICLE"="Article" "IMAGE"="Media")
 */

应该是:

/**
 * @ORM\DiscriminatorMap("ITEM"="Item", "ARTICLE"="Article", "IMAGE"="Media")
 *                                                          ^
 */

我不太确定,但可能是鉴别器映射需要完全限定的类名:

/**
 * @ORM\DiscriminatorMap(
 *     "ITEM"="Beachteam\BeachteamBundle\Entity\Item",
 *     "ARTICLE"="Beachteam\BeachteamBundle\Entity\Article",
 *     "IMAGE"="Beachteam\BeachteamBundle\Entity\Media"
 * )
 */

接下来您需要从Item 中删除属性$type,因为type 已被用作鉴别器列。

您可能还想使用控制台来验证您的映射:

app/console doctrine:schema:validate

修复所有可能报告的错误。

更新

属性 Beachteam\BeachteamBundle\Entity\Item::$type 不存在

这意味着在代码中的某处(现在不存在)属性$type 的类Item 仍在使用中。你必须追查到哪里。

在您的代码中搜索-&gt;type。 清除缓存(删除app/cache文件夹的内容并运行app/console cache:clear

【讨论】:

当我修复我的 DiscriminatorMap 并删除我的类型变量 + getter/setter 并验证我的模式时,我得到:Property Beachteam\BeachteamBundle\Entity\Item::$type 不存在【参考方案2】:

我认为您在生成学说作为继承属性时计划了 Item::$type 属性。但这也是通过注解创建的:

@ORM\DiscriminatorColumn(name="type", type="string")

您的表键和字段的一部分具有相同的名称。尝试删除类属性(和getter、setter方法),然后更新架构

php app/console doctrine:schema:update --force

在此更改之后,您的课程就像我的盒子上的魅力一样

祝你好运!

【讨论】:

当我尝试更新时,我得到:属性 Beachteam\BeachteamBundle\Entity\Item::$type 不存在 我看到你更新了 Item 实体,现在它丢失了` * @ORM\DiscriminatorColumn(name="type", type="string")` 留下注释但删除变量 $type 现在你有两个 @ORM\DiscriminatorMap 注释。删除一个,我不确定女巫是否在你的班上工作 你能描述一下你什么时候遇到这个错误吗?我已经复制粘贴了您的代码,但它仍然可以正常工作。也许我错过了您执行的某些行为或动作。另一方面,当我使用教义:架构:验证所有我可以看到 @ORM\ManyToOne(targetEntity="Beachteam\BeachteamBundle\Entity\User") 缺少 inversedBy 声明。就是这样。 还有一件事:请发布 Symfony 和 php 版本。 我正在使用 Symfony 2.4.1 和 PHP 5.4.20

以上是关于复合标识符,但使用 ID 生成器而不是手动分配 + Symfony2的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate JPA 序列(非 Id)

Fluent NHibernate 多对多映射,使用自动生成的 pk 而不是复合键

USB 复合设备实例 ID

为啥在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格?

什么是复合主键

为什么MySQL只使用复合索引而不是单独的索引?