2011-06-17 6 views
7

que tienen las dos tablas:clave principal y clave externa al mismo tiempo con la doctrina 2

mesa Un con Identificación como clave primaria

mesa B con Identificación como primaria llave y clave externa

Explicación de resumen:

I nee d tener en la tabla B una clave principal que también debe ser una clave externa que apunta a la tabla A 's clave principal.

¿Alguien me puede explicar cómo hacer un mapa de esto mediante anotaciones en Doctrine 2?

Nota:

Yo probé Por esto:

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

y B tabla:


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

pero me da este error:

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: No debo tener una clave primaria compuesta.

Respuesta

1

Finalmente resolví mi problema especificando dos campos en mi clase de entidad para la misma columna de la tabla de verdad. Los cambios se realizan sólo en la clase B (ver la cuestión de clase 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; 

... 

De hecho, todo lo que he hecho es escribir dos campos en mi entidad para la misma clave principal y clave externa.

11

Esto es posible ya 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

esto es ** ya ** posible. :) [Descargar Doctrine 2.1] (http://www.doctrine-project.org/projects/orm/2.1/download/2.1.0) – JCM

1

Bueno esta es otra solución temporal para la inserción:

/** 
    * @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(); 

este inserto en una clase con la clave externa y la clave principal en el lenguaje

1

que podía resolver el problema, creando un campo pk con el mismo nombre al campo extranjero

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

que tenían la misma tarea y experimentalmente encontró esta solución:

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; 

} 
Cuestiones relacionadas