Doctrine2 — один ко многим

Автор: Aport Суббота, Январь 31st, 2015 Нет комментариев

Рубрика: MySQL

Нюансы работы внешних ключей на примере ORM Doctrine2.

Для начала нам понадобятся 2 сущности, например People и News.

Имеем ввиду, что один пользователь может опубликовать несколько новостей (связь один ко многим).

Давайте опишем эти 2 сущности:

<?php
namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class People
{
    /**
     * переменная нужна, чтобы идентифицировать человека
     * @ORM\Id
     * @ORM\Column(type="integer", options={"unsigned": true, "comment" : "ID человека"})
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id = 0;

    /**
     * @ORM\Column(type="string", length=255, options={"default":""})
     */
    private $name = '';

}

и вторая сущность:

<?php
namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class News
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", options={"unsigned": true, "comment" : "ID новости"})
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id = 0;

    /**
     * @ORM\Column(type="string", length=255, options={"default":""})
     */
    private $title = '';

    /**
     * ID человека
     * @ORM\ManyToOne(targetEntity="Acme\DemoBundle\Entity\People")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="peopleId", referencedColumnName="id")
     * })
     */
    private $peopleId = 0;

}

Теперь создадим таблицы в базе данных:

$ app/console doctrine:schema:update —force

И попробуем добавлять записи в базу:

INSERT INTO People (‘name’) VALUES (‘ivan’);// хорошо, строке присвоен id = 1

INSERT INTO News SET title = ‘Привет‘, peopleId = 1;// хорошо, строка добавилась

INSERT INTO News SET title = ‘Мир‘, peopleId = 2;// хорошо, строка НЕ добавилась, т.к. в People нет строки с id = 2

INSERT INTO News SET title = ‘Труд;// ужас, строка добавилась, поле peopleId = NULL

Плохо — целостность потеряна! А ведь нам нужно, чтобы последний запрос не сработал, т.к. мы не указали peopleId

Мало того, мы спокойно можем выполнить запросы:

UPDATE News SET peopleId = 1 WHERE id = 1;

UPDATE News SET peopleId = NULL WHERE id = 1;

Кошмар, значит все новости могут потерять владельцев, и не поверите, но это нормальная ситуация, оказывается NULL это значение по-умолчанию.

Но, решить эту проблему все таки можно, хотя и к сожалению не для тех строк, которые уже были добавлены.

Для решения проблемы, полю peopleId нужно указать значение по-умолчанию NOT NULL

В Doctrine2 анотации это делается так:

@ORM\JoinColumn(name=»peopleId», referencedColumnName=»id», nullable=false)

Проверим добавление строки в базу данных:

INSERT INTO News SET title = ‘Май’;// ура, строка НЕ добавилась

INSERT INTO News SET title = ‘Мир‘, peopleId = 0;// ура, строка НЕ добавилась

Теперь консистентность данных в порядке (если не брать в счет тех строк, которые были добавлены до значения по-умолчанию NOT NULL).

Удачи господа.

 

Источник: yapro.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты