2016-10-04 115 views
1

我希望这是一个直截了当的过程,但看起来Doctrine并不喜欢通过它们的ID链接实体的想法。如何通过教义实体之间的ID建立一对一的关系

所有我打算做的是通过将一些字段从它传送到一个新表来正常化一个表,而不是向原始表中添加新的引用字段来保存新的对应记录的ID,请确保子表中的新记录将具有与其父行相同的ID。

这里是什么,我有一个例子:

一个用户实体,与标注的字段$user引用在UserDetail实体列ID自身的ID

/** 
* @ORM\Table(name="user", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"}) 
* @ORM\Entity 
*/ 
class User extends Entity 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id 

    /** 
     * @ORM\OneToOne(targetEntity="UserDetail", cascade={"persist"}) 
     * @ORM\JoinColumn(name="id", referencedColumnName="id", nullable=true) 
     */ 
    private $userDetail; 

    ... 
} 

,这里是UserDetail删除了ID的@GeneratedValue

/** 
* @ORM\Table(name="user_detail", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"}) 
* @ORM\Entity 
*/ 
class UserDetail extends Entity 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    */ 
    private $id; 

    ... 
} 

在这一点上有什么我的期望是能够做一些事情,如:

$user = new User(); 
$userDetail = new UserDetail(); 

$user->setUserDetail($userDetail) 

$entityManager->persist($user); 
$entityManager->flush(); 

并获得两项纪录保持到用户user_detail表与相同 ID,但现实的情况是,没有为UserDetail的标识符定义任何策略,原则将投诉丢失的ID,Entity of type UserDetail is missing an assigned ID for field 'id'.

当然,可以手动完成这项工作,并且可以在多个呼叫中进行

$user = new User(); 
$entityManager->persist($user); 
$entityManager->flush(); 

$userDetail = new UserDetail(); 
$userDetail->setId($user->getId)  
$user->setUserDetail($userDetail) 

$entityManager->persist($user); 
$entityManager->flush(); 

但我还是希望能有一个正确的配置(注释),可以帮助我避免这种额外的步骤,并通过实体的ID来学说留下一个一对一关系的处理。

+2

人生苦短,担心这样的事情。将UserDetail :: id定义为基本的autoinc主键,然后添加一个user_id列以用作用户的引用。而且我知道。你想让它们保持同步并且没有额外的数据库列,但它真的很重要吗?当使用Doctrine认为对象不是数据库和生活会很好。 – Cerad

+0

@Cerad大声笑,不能同意更多,但不幸的是,在这个应用程序中,我们的团队(公司)不负责数据库,并且包括额外的列是没有问题的,因为还有其他消费者(基于Java)可以处理这样的场景更容易 – Ali

+1

我看到这个问题问几次,但从来没有见过一个开箱即用的解决方案。应该能够实现您自己的自定义ID生成器。在这方面没有找到任何好的最新教程,但你可以从这里开始:https://groups.google.com/forum/#!topic/doctrine-user/GxXAO3-g4vo – Cerad

回答

1

这是未经测试,但我认为有以下可能的工作,根据文档(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html):

/** 
    * @ORM\Table(name="user_detail", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"}) 
    * @ORM\Entity 
    */ 
    class UserDetail extends Entity 
    { 
     /** 
     * @var integer 
     * 
     * @ORM\OneToOne(targetEntity="User") 
     * @ORM\JoinColumn(name="id", referencedColumnName="id") 
     * @ORM\Id 
     */ 
     private $user; 

    ... 
    } 
+0

谢谢你会我会试试看,让你知道它是否有效 – Ali

+0

不幸的是,这不起作用,它实际上导致了一个无限循环,函数嵌套级别'1000'到达,放弃!|| {“file”:“Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory。php“,”line“:187' – Ali

+0

对不起阿里,我已经调整了我的答案中的代码 - 我的意思是它与用户实体是正确的关联,但忘记更改属性名称 – Will

相关问题