6

一部のエンティティオブジェクトでIDを設定でき、他のオブジェクトではエラーが発生し、IDをnullにできないため、代わりにオブジェクトを渡す必要がある理由を理解していません。

例えば:

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

上記のコードを試してみると、次のようなエラーが発生します。整合性制約違反:1048列'user_id'をnullにすることはできません。そして、最初にTypeObjectオブジェクトとdeUserオブジェクトを作成し、それらを渡す必要があります。

$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、$識別子)を使用すると、データベースからエンティティをロードせずに、識別子がわかっているエンティティへの参照を取得できます。これは、たとえば、識別子を持つエンティティへの関連付けを確立する場合に、パフォーマンスの向上として役立ちます。あなたは単にこれを行うことができます:

<?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へのマッピングを行います。

ここで行ったことは少し冗長です。

あなたは本質的に同じことを2回教義に話しました。

'user_id'列があり、Userオブジェクトもあることを伝えました。これは同じことです。しかし、Doctrineは、ログクラスにユーザーオブジェクトが含まれているという事実に基づいて、この関係に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を気にすることなく、プログラミングが容易になります。Doctrineがそれを処理します。

フロントエンドで使用しているのがIDである場合は、Entitymanagerを使用してそのIDに関連付けられたオブジェクトをフェッチするだけです。

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