【问题标题】:Primary key and foreign key at the same time with doctrine 2主键和外键同时用学说2
【发布时间】:2011-09-17 01:23:44
【问题描述】:

我有两张桌子:

id为主键的A

Bid 作为主键和外键

简短说明:

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

谁能解释我如何通过 Doctrine 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\映射\映射异常' 带有消息'没有标识符/主要 为实体“B”指定的键。每一个 实体必须有一个标识符/主要 钥匙。'在 /var/www/agr-reg-php/Doctrine/ORM/Mapping/MappingException.php:37 堆栈跟踪:

注意:我不能有复合主键。

【问题讨论】:

    标签: php orm foreign-keys primary-key doctrine-orm


    【解决方案1】:

    这是可能的,因为Doctrine 2.1

    通过外来实体或派生实体的身份:您现在可以使用外键作为实体的标识符。这转化为在 @ManyToOne 或 @OneToOne 关联上使用 @Id。你可以阅读这个feature in the tutorial

    【讨论】:

    【解决方案2】:

    我有同样的任务并且实验性地找到了这个解决方案:

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

    【讨论】:

      【解决方案3】:

      我可以解决这个问题,创建一个与外部字段同名的 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;
      //...
      

      【讨论】:

      • 这对我帮助很大!
      【解决方案4】:

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

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

      在类中插入外键和主键的语言

      【讨论】:

        【解决方案5】:

        最后,我通过在实体类中为真实表中的同一列指定两个字段来解决我的问题。更改仅在 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;
        
        ...
        

        事实上,我所做的只是在我的实体中为相同的主键和外键编写两个字段。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-09
          • 1970-01-01
          • 1970-01-01
          • 2013-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多