6

我不明白为什么使用某些 Entity 对象我可以设置 Id 而对于其他对象我得到一个错误,并说我 Id 不能为空,我必须传递一个对象。

例如:

$log = new Log();
$log->setTypeId(1);
$log->setUserId(1);
$entityManager->persist($log);
$entityManager->flush();

如果我尝试上面的代码,我会收到错误消息:Integrity constraint violation: 1048 Column 'user_id' cannot be null。我必须首先创建 Type Object 和 de User 对象并传递它们:

$log->setType($TypeObject)
$log->setUser($UserObject)

但是对于其他实体对象,我直接赋值没有问题,这是为什么呢?

这是我的实体日志:

<?php
/**
 * @Entity
 * @Table(name="log")
 * @HasLifecycleCallbacks
 */
class Log
{
    /**
     * @var type 
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;

     /**
     *
     * @var type 
     * @Column(type="integer")
     */
    protected $user_id;

     /**
     *
     * @var type 
     * @Column(type="integer")
     */
    protected $type_id;

     /**
     *
     * @var type 
     * @Column(type="datetime")
     */
    protected $created;

    /**
     *
     * @var type 
     * @ManyToOne(targetEntity="User", inversedBy="logs")
     */
    protected $user;

    /**
     *
     * @ManyToOne(targetEntity="Type", inversedBy="logs")
     */
    protected $type;

    public function getId()
    {
        return $this->id;
    }

    public function getUserId()
    {
        return $this->user_id;
    }

    public function getTypeId()
    {
        return $this->type_id;
    }

    public function getCreated()
    {
        return $this->created;
    }

    public function setUserId($userId)
    {
        $this->user_id = $userId;
    }

    public function setTypeId($typeId)
    {
        $this->type_id = $typeId;
    }

    public function setCreated($created)
    {
        $this->created = $created;
    }

    public function setUser($user)
    {
        $this->user = $user;
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    /**
     * @PrePersist
     */
    public function prePersist()
    {
        $this->setCreated(new DateTime());
    }

}
?>
4

2 回答 2

30

现有的答案从来没有让我满意。在许多有效的场景中,加载一个对象只是为了定义关系,而 FK 已经很方便了,这根本没有任何意义。

更好的解决方案是使用 Doctrine 的 EntityManager 的getRefrence方法。

参考代理...

EntityManager#getReference($entityName, $identifier) 方法允许您获取对已知标识符的实体的引用,而无需从数据库中加载该实体。这很有用,例如,当您想要建立与您拥有标识符的实体的关联时,作为性能增强。你可以简单地这样做:

<?php
  // $em instanceof EntityManager, $cart instanceof MyProject\Model\Cart
  // $itemId comes from somewhere, probably a request parameter
  $item = $em->getReference(\MyProject\Model\Item::class, $itemId);
  $cart->addItem($item);

首次发布此问题时,也许这不可用-我不知道。

于 2014-01-31T19:06:17.850 回答
3

编辑

我在 Doctrine2 的网站上找到了这个声明。这是您在编写模型时可能需要遵循的最佳实践。

Doctrine2 最佳实践

25.9。不要将外键映射到实体中的字段

外键在对象模型中没有任何意义。外键是关系数据库建立关系的方式。您的对象模型通过对象引用建立关系。因此,将外键映射到对象字段会严重地将关系模型的细节泄漏到对象模型中,这是您真正不应该做的事情

编辑

Doctrine 将您的对象映射到它们各自的 Id。

你在这里所做的有点多余。

你基本上已经两次告诉教义同样的事情。

您已经告诉它它有一个“user_id”列并且它也有一个用户对象,它们是相同的。但是学说已经可以根据日志类里面有一个用户对象这一事实,猜到这个关系会有一个user_id列。

您应该简单地执行以下操作

<?php
/**
 * @Entity
 * @Table(name="log")
 * @HasLifecycleCallbacks
 */
class Log
{
    /**
     * @var type 
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;

     /**
     *
     * @var type 
     * @Column(type="datetime")
     */
    protected $created;

    /**
     *
     * @var type 
     * @ManyToOne(targetEntity="User", inversedBy="logs")
     */
    protected $user;

    /**
     *
     * @ManyToOne(targetEntity="Type", inversedBy="logs")
     */
    protected $type;

    public function getId()
    {
        return $this->id;
    }

    public function getCreated()
    {
        return $this->created;
    }

    public function setCreated($created)
    {
        $this->created = $created;
    }

    public function setUser($user)
    {
        $this->user = $user;
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    /**
     * @PrePersist
     */
    public function prePersist()
    {
        $this->setCreated(new DateTime());
    }

}

Doctrine 会自己担心 user_id 和 type_id。你不必担心。通过这种方式,您可以使用完整的对象,使其更容易编程,而不必担心 id。教义会处理这个问题。

如果您拥有的只是一个 id,因为这就是您在前端使用的,那么只需使用 Entitymanager 获取与该 id 关联的对象。

$user = $em->getEntity( 'User', $idFromWeb );
$log = new Log();
$log->setUser( $user );
于 2012-07-30T18:03:44.823 回答