Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

composite identifier, but uses an ID generator other than manually assigning + Symfony2

I have three tables.

item with fields

    PK id
    title
    description
    type
    created
    delete
    fk user_id

article with fields

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

media with fields

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

The type field in article table is an ENUM with values ITEM, ARTICLE and IMAGE.
The entities are autogenerated. So, originally the Article Entity doesn't extends the Item Entity. I had to change that.

I always get this error:

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

UPDATE:
After deleting my type variable and fixing the discriminatormap I get this error:

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

This is my updated Item Entity:

<?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;
    }
}

This is my updated Article Entity:

<?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;
    }
}

Can anyone explain me the error (internet didn't help me much).. And why do I get this error?

P.S.: I'm using Symfony 2.4.1 and PHP 5.4.20

like image 266
nielsv Avatar asked Feb 18 '14 19:02

nielsv


People also ask

What are composite identifiers in JPA?

Composite Identifiers are also known as Derived identities. All the rules applied for a Simple Primary Key also applies for a composite primary key. There are rules that govern the usage of the composite identifier in JPA. The composite primary keys must be represented by a “primary key class”.

How to define a composite identifier in Entity Framework?

Another way to define the composite identifier is by using @IdClass annotation. Annotate the @Entity class with @IdClass (ClassName) and annotate the fields of Entity class with @Id. Below is the code snippet.

How to define the composite primary keys in Java?

In order to define the composite primary keys, we should follow some rules: The composite primary key class must be public. It must have a no-arg constructor. It must define the equals () and hashCode () methods. It must be Serializable.

How to generate more complex id values in JPA and hibernate?

JPA and Hibernate support a set of standard id generators which enable you to use database sequences and auto-incremented columns. If you need to generate more complex values that contain additional semantic information, you can extend the existing generators.


2 Answers

I think this line (in Item):

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

should be:

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

I'm not really sure, but it could be that the discriminator map needs fully qualified classnames:

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

Next you will need to remove the property $type from Item, because type is already used as discriminator column.

You might also want to use the console to validate your mappings:

app/console doctrine:schema:validate

Fix all errors that might be reported.

update

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

This means that somewhere in the code the (now non-existent) property $type of class Item is still being used. You'll have to track down where.

  • Search your code for ->type.
  • Clear the cache (delete the content of the app/cache folder and run app/console cache:clear.
like image 143
Jasper N. Brouwer Avatar answered Sep 24 '22 16:09

Jasper N. Brouwer


I think that you planed Item::$type attribute while generating doctrine as a inheritance attribute. But this is also created by annotation:

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

You have part of a table key and field with the same name. Try to remove class attribute (and getter, setter method), then update schema

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

After this change your classes works like a charm on my box

Good Luck!

like image 41
WebHQ Avatar answered Sep 26 '22 16:09

WebHQ