13

配列型フィールドを持つDoctrineエンティティがあります:

/**
 * @ORM\Table()
 */
class MyEntity
{
    (...)

    /**
     * @var array $items
     * 
     * @ORM\Column( type="array" ) 
     */
    private $items;

    /**
     * @param SomeItem $item 
     */
    public function addItem(SomeItem $item)
    {
        $this->items[] = $item;
    }

    (...)
}

配列に要素を追加すると、このコードは正しく機能します。

$myEntityObject->addItems(new SomeItem()); 
$EntityManager->persist($myEntityObject);
$EntityManager->flush();

$myEntityObject正しいデータでデータベースに保存されます (配列はシリアル化され、データベースのクエリ時に逆シリアル化されます)。

残念ながら、配列のサイズを変更せずに配列内のオブジェクトの 1 つを変更すると、Doctrine は変更をデータベースに保存しようとしても何もしません。

$items = $myEntityObject->getItems();
$items[0]->setSomething(123);
$myEntityObject->setItems($items);
$EntityManager->persist($myEntityObject);
$EntityManager->flush();
print_r($myEntityObject);

そのprint_rコードの最後の行では、変更されたオブジェクトのデータが表示されますが、Doctrine は配列サイズが変更されていない場合、配列内で何かが変更されたことを知りません。そのフィールドで行われた変更をDoctrineに強制的に保存させる方法はありますか(または、保存する必要があるそのフィールドの変更について穏やかに通知します)?


ドキュメントで私の問題を解決する方法を見つけました:

http://docs.doctrine-project.org/en/latest/reference/change-tracking-policies.html

コードに多くの変更が必要ですが、機能します。他のフィールドのデフォルトの追跡ポリシーを保持し、配列を格納するフィールドだけに NotifyPropertyChanged を使用する方法を知っている人はいますか?

4

3 に答える 3

1

コードでこれを修正する方法は、createQueryBuilder を使用して更新クエリを作成することでした。このように、教義はノーと言う方法はありません:)

だから私はこれから行きました

$em          = $this->getDoctrine()->getManager();
$matchEntity = $em->getReference('MyBundleBundle:Match', $match_id);


$matchEntity->setElement($element);
$matchEntity->setTeamHomeColour($data['team_a_colour']);
$matchEntity->setTeamAwayColour($data['team_b_colour']);

これに:

$repository = $this->getDoctrine()->getRepository('MyBundleBundle:Match');
$query      = $repository->createQueryBuilder('u')
    ->update()
    ->set('u.element', ':element')
    ->set('u.teamHomeColour', ':thomecolour')
    ->set('u.teamAwayColour', ':tawaycolour')
    ->where('u.matchId = :match')

    ->setParameter('element', $element)
    ->setParameter('thomecolour', $data['team_a_colour'])
    ->setParameter('tawaycolour', $data['team_b_colour'])
    ->setParameter('match', $matchEntity)

    ->getQuery();

$query->execute();

数行のコードが追加されていますが、クローン作成やその他の魔法はありません。いまいましい更新を行うようにdoctrineに直接指示するだけです! お役に立てれば。

注: 私の状況では、設定されていなかったのは $element でした。以前のクエリですべての一致を設定解除しましたが、教義がそれを表示しなかったため、要素の更新を拒否しました。

于 2015-06-30T17:19:37.423 に答える