2011-06-17 147 views
7

我有两个表:主键和外键2

ID作为主键

ID作为主钥匙和外钥匙

简短说明:

我需要d在表B中也有一个主键也是指向表A的主键。

任何人都可以解释我如何通过Doctrine 2中的注释来映射这个吗?

注:

我试了一下通过这个:

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

表:


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

但它给我这个错误:

Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'No identifier/primary key specified for Entity 'B'. Every Entity must have an identifier/primary key.' in /var/www/agr-reg-php/Doctrine/ORM/Mapping/MappingException.php:37 Stack trace:

N.B:我不能有复合主键。

回答

1

最后,我在我的实体类指定两个字段从实际表相同的列解决我的问题。这些变化只在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; 

... 

事实上,所有我所做的就是写在我的实体上的两个字段相同的主键和外键。

11

这是可能的,因为Doctrine 2.1

Identity through Foreign Entities or derived entities: You can now use a foreign key as identifier of an entity. This translates to using @Id on a @ManyToOne or @OneToOne association. You can read up on this feature in the tutorial .

+1

这是**已经**可能。 :) [下载Doctrine 2.1](http://www.doctrine-project.org/projects/orm/2.1/download/2.1.0) – JCM 2011-07-08 02:54:44

1

嗯,这是插入其他时间的解决方案:

/** 
    * @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

外键和主键,我可以解决这个问题,创建与一个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

我有同样的任务,experimentaly发现此解决方案:

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; 

}