Первичный ключ и внешний ключ одновременно с доктриной 2 - PullRequest
9 голосов
/ 17 июня 2011

У меня есть две таблицы:

таблица A с id в качестве первичного ключа

таблица B с id в качестве первичного и внешнего ключа

Объяснение вкратце:

Мне нужно иметь в таблице B первичный ключ, который также должен быть внешним ключом, указывающим на первичный ключ A таблицы.

Кто-нибудь может объяснить мне, как сопоставить это с помощью аннотаций в Учении 2?

Примечание:

Я попробовал это:

   class A
{
    /**
     * @var bigint $id
     *
     * @Column(name="id", type="bigint", nullable=false)
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    private $a_id;
...

и B Таблица:


class B
{
    /**
     * @var bigint $id
     * @Id 
     * @OneToOne(targetEntity="A", fetch="LAZY")
     * @JoinColumn(name="id", referencedColumnName="id")
     */
    private $b_id;
...

Но это дает мне эту ошибку:

Неисследованное исключение 'Учение \ ORM \ Mapping \ MappingException' с сообщением «Нет идентификатора / основной ключ указан для сущности "B". каждый Сущность должна иметь идентификатор / основной ключ «. в /var/www/agr-reg-php/Doctrine/ORM/Mapping/MappingException.php:37 Трассировка стека:

N.B: У меня не должно быть составного первичного ключа.

Ответы [ 5 ]

10 голосов
/ 17 июня 2011

Это возможно начиная с Доктрины 2.1 :

Идентификация через иностранные или производные объекты : теперь вы можете использовать внешний ключ в качестве идентификатора объекта. Это означает использование @Id в ассоциации @ManyToOne или @OneToOne. Вы можете прочитать об этой функции в руководстве .

2 голосов
/ 23 октября 2012

Я мог бы решить проблему, создав поле pk с тем же именем, что и чужое поле

class B
{
/**
 * @var bigint $a_id
 * @Id @Column(name="a_id", type="bigint", nullable="false")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $a_id;

/**
 * @OneToOne(targetEntity="A", fetch="LAZY")
 * @JoinColumn(name="id", referencedColumnName="id")
 */
private $a;
.
.
.
/**
 * @var A
 *
 * @ORM\OneToOne(targetEntity="A")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="a_id", referencedColumnName="id", unique=true)
 * })
 */
private $a;
//...
1 голос
/ 31 октября 2012

У меня была та же задача, и экспериментально нашел это решение:

class A {  
    /**  
    * @Id @Column(type="integer", nullable=false)  
    * @GeneratedValue  
    */  
    protected $id;  

    /**  
     * @OneToOne(targetEntity="B", inversedBy="a", orphanRemoval=true, cascade={"persist", "remove"})  
     * @JoinColumn(name="id", referencedColumnName="id")  
     */  
    protected $b;  

}  

class B {  
    /**  
     * @OneToOne(targetEntity="A", mappedBy="b" )  
     */  
    protected $user;  

    /**  
     * @Id  
     * @Column(type="integer", nullable=false)  
     * @GeneratedValue  
     */  
    protected $id;  

}  
1 голос
/ 25 июля 2012

Ну, это другое временное решение для вставки:

    /**
     * @Entity
     * @Table(name="types")
     */
    class Type {
    /**
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    private $id;
    /**
     * @OneToMany(targetEntity="type\models\Language", mappedBy="type")
     */
    private $languages;

    /**
     * @Column(type="string", length = 45,nullable = true)
     */
    private $category;

    /**
     * @Column(type="string", length = 1)
     */
    private $status;

    /**
     * @Column(type="string", length = 45)
     */
    private $name;

    /**
     * @Column(type="datetime", nullable = true)
     */
    private $datedeleted;

    /**
     * @Column(type="datetime", nullable = true)
     */
    private $datemodificated;

    /**
     * @Column(type="datetime")
     */
    private $dateregistered;

    public function __construct() {
        $this->languages = new \Doctrine\Common\Collections\ArrayCollection;
        $this->status = 1;
        $this->dateregistered = new \DateTime("now");
    }

    public function id() {
            return $this->id;
    }

    public function category($value = NULL) {
        if (is_null($value))
            return $this->category;
        else
            $this->category = $value;
    }

    public function name($value = NULL) {
        if (is_null($value))
            return $this->name;
        else
            $this->name = $value;
    }

    public function status($value = NULL) {
        if (is_null($value))
            return $this->status;
        else
            $this->status = $value;
    }

    public function datedeleted($value = NULL) {
        if (is_null($value))
            return $this->datedeleted;
        else
            $this->datedeleted = $value;
    }

    public function datemodificated($value = NULL) {
        if (is_null($value))
            return $this->datemodificated;
        else
            $this->datemodificated = $value;
    }

    public function dateregistered($value = NULL) {
        if (is_null($value))
            return $this->dateregistered;
        else
            $this->dateregistered = $value;
        }
    }

    /**
     * @Entity
     * @Table(name="languages")
     */
    class Language {

    /**
     * @Id 
     * @Column(name="type_id", type="integer", nullable="false")
     */
    private $language_id;

    /**
     * @Id
     * @ManyToOne(targetEntity="type\models\Type",inversedBy="languages")
     * @JoinColumn(name="type_id", referencedColumnName="id")
     */
    private $type;

    /**
     * @Column(type="string", length = 100, nullable = true)
     */
    private $description;

    /**
     * @Id
     * @Column(type="string", length = 20)
     */
    private $language;

    public function language_id($value) {
        $this->language_id = $value;
    }

    public function description($value = NULL) {
        if (is_null($value))
            return $this->description;
        else
            $this->description = $value;
    }

    public function language($value = NULL) {
        if (is_null($value))
            return $this->language;
        else
            $this->language = $value;
    }

    public function type($value = NULL) {
        if (is_null($value))
            return $this->type;
        else
            $this->type = $value;


     }
    }

$language = new Language;
$xtype_id = $this->em->find("Type",1);
$language->language_id($xtype_id->id());
$language->type($xtype_id);
$language->description($xdescription);
$language->language($xlanguage);
$this->em->persist($this);
$this->em->flush();

эта вставка в классе с внешним ключом и первичным ключом на языке

1 голос
/ 28 июня 2011

Наконец, я решил свою проблему, указав два поля в моем классе сущности для одного и того же столбца из реальной таблицы. Изменения сделаны только в классе B (посмотрите на вопрос для класса A):


class B
{
    /**
     * @var bigint $id
     * @Id @Column(name="id", type="bigint", nullable="false")
     */
    private $b_id;

    /**
     * @OneToOne(targetEntity="A", fetch="LAZY")
     * @JoinColumn(name="id", referencedColumnName="id")
     */
    private $a;

...

На самом деле все, что я сделал, - написал два поля в моей сущности для одного и того же первичного ключа и внешнего ключа.

...