Doctrine - 如何在两个实体之间建立一对一关系

3
我有两个表格: Users 和 Contacts
用户表 - id - 用户名
联系人表 - id - 用户id - 邮箱 (我简化了结构)
那么,如何正确设置Doctrine实体?
/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseEntity {

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     */
     protected $id;

    /**
     * @ORM\Column(type="string", unique=true)
     */
    protected $username;

    /**
     * @ORM\OneToOne(targetEntity="Contact")
     * @ORM\JoinColumn(name="id", referencedColumnName="user_id", onDelete="CASCADE")
     **/
    protected $contact;
}

联系人实体:

/**
 * @ORM\Entity
 * @ORM\Table(name="contacts")
 */
class Contact extends BaseEntity {

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     */
     protected $id;

    /**
     * @var User
     * @ORM\OneToOne(targetEntity="User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    /**
     * @ORM\Column(type="string")
     */
    protected $email;
}

事情是这样的,我不确定实体关系是否设置正确。
  1. 我不知道如何设置如果删除 User 则删除 Contact,但反过来不行。
  2. 如果我创建了 $user = new User(),然后 $contact = new Contact(),如何连接它们? $user->contact = $contact? 在 persist()flush() 之后,它会正确地填充 user_id 并将数据插入两个表中吗?
  3. 我遇到了错误 A new entity was found through the relationship '...\User#contact' that was not configured to cascade persist operations for entity: ...\Contact@0000000015f3aa5e000000012cd799f5. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement '...\Contact#__toString()' to get a clue. 我被卡住了,我认为这与我的问题 #1 有关,因此我无法测试 #2。

我已经浏览了几个小时的文档,但我被卡住了,我没有找到任何真正的示例可以引导我... 有人可以通过向我展示这些实体之间关系的适当配置来帮助我吗?

1个回答

6
为了使用户删除的同时也删除其联系人,需要在Contact实体中,在$user属性的JoinColumn注释中添加onDelete="CASCADE"(这只会在联系人所属的用户被删除时才删除该联系人)。
/**
 * @var User
 * @ORM\OneToOne(targetEntity="User")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
 */
private $user;

如果在将联系人添加到用户之前持久化该联系人,则不应出现任何错误。如果您想通过直接将新的未持久化的联系人分配给用户来添加新联系人, 那么您需要将 cascade={"persist", "remove"} 添加到您的 User 实体。

/**
 * @ORM\OneToOne(targetEntity="Contact",cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="id", referencedColumnName="user_id")
 **/
protected $contact;

好的,谢谢,听起来不错。但是,我尝试设置 cascade={"persist", "remove"}),当我执行 $user = new User() $contact = new Contact() $user->contact = $contact $entityManager->persist($user) $entityManager->flush() 时,用户被创建了,但联系人没有被创建。我做错了什么? - simPod
如果我手动调用 persist($contact),它可以工作。我必须这样做吗?还是可以通过 @ORM 注释来包含它? - simPod
1
@simPod,将cascade={"persist", "remove"}添加到您的User实体的$contact属性中,应该允许您向User添加未持久化的联系人。您的User实体中是否有其他映射可能会导致问题? - FuzzyTree

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接