前回の続きです。
今回は変更についてです。
use App\Entities\Item;
use Doctrine\ORM\EntityManager;
/** @var EntityManager $manager */
$manager = require 'createManager.php';
$work = $manager->getUnitOfWork();
/** @var array<Item> $items */
$items = $manager->getRepository(Item::class)->findAll();
// IDが1と4のエンティティを変更
$items[0]->setPower(123);
$items[3]->setPower(456);
$items[3]->setName('QQQ');
// id = 2 を削除
$manager->remove($items[1]);
// id = 5 を外す
$manager->detach($items[4]);
// Add(StateはManagedになるがIdentiferMapには登録されない)
$addItem = new Item('XXX', 123);
$manager->persist($addItem);
// New(インスタンスを作っただけ)
$newItem = new Item('YYY', 456);
// 管理エンティティから変更を算出(このメソッドはflush()時にも呼び出さえれる)
$work->computeChangeSets();
foreach([...$items, $addItem, $newItem] as $item)
{
$set = $work->getEntityChangeSet($item);
if($set)
{
print_r($item);
print_r($set);
echo "------------------------------------\n";
}
}
App\Entities\Item Object
(
[id:App\Entities\Item:private] => 1
[name:App\Entities\Item:private] => F
[power:App\Entities\Item:private] => 123
)
Array
(
[power] => Array
(
[0] => 8
[1] => 123
)
)
------------------------------------
App\Entities\Item Object
(
[id:App\Entities\Item:private] => 4
[name:App\Entities\Item:private] => QQQ
[power:App\Entities\Item:private] => 456
)
Array
(
[name] => Array
(
[0] => D
[1] => QQQ
)
[power] => Array
(
[0] => 5
[1] => 456
)
)
------------------------------------
App\Entities\Item Object
(
[name:App\Entities\Item:private] => XXX
[power:App\Entities\Item:private] => 123
)
Array
(
[name] => Array
(
[0] =>
[1] => XXX
)
[power] => Array
(
[0] =>
[1] => 123
)
)
------------------------------------
まずIDが1と4のItemに変更を加えます。
$items[0]->setPower(123);
$items[3]->setPower(456);
$items[3]->setName('QQQ');
次にcomputeChangeSets()
で変更を算出し取得できるようにします。
このメソッドはflush()
時に内部で呼び出されるようですが、今回は変更を知るためこのタイミングで呼び出します。
$work->computeChangeSets();
エンティティごとに変更を算出するcomputeChangeSet()
もありますがここには触れません。
idが1のエンティティはpower
が8
から123
へ変更されていることが確認できます。
[power] => Array(
[0] => 8
[1] => 123
)
idが4のエンティティはpower
が5
から456
へ、name
がD
からQQQ
への変更が確認できます。
追加したエンティティはそれぞれpower
がnull
から123
へ、name
がnull
からXXX
へ変更されてます。
変更算出
computeChangeSets()
を実行しないと変更が反映されてないことが分ります
use App\Entities\Item;
use Doctrine\ORM\EntityManager;
/** @var EntityManager $manager */
$manager = require 'createManager.php';
$work = $manager->getUnitOfWork();
/** @var Item $item */
$item = $manager->find(Item::class, 1);
print_r($item);
// 1
$item->setName('QQQ');
print_r($work->getEntityChangeSet($item));
// 2
$work->computeChangeSets();
print_r($work->getEntityChangeSet($item));
// 3
$item->setName('WWWWWWWWW');
print_r($work->getEntityChangeSet($item));
// 4
$item->setName('XXXXXXXXXXXXXX');
// 5
$work->computeChangeSets();
print_r($work->getEntityChangeSet($item));
App\Entities\Item Object
(
[id:App\Entities\Item:private] => 1
[name:App\Entities\Item:private] => F
[power:App\Entities\Item:private] => 8
)
Array
(
)
Array
(
[name] => Array
(
[0] => F
[1] => QQQ
)
)
Array
(
[name] => Array
(
[0] => F
[1] => QQQ
)
)
Array
(
[name] => Array
(
[0] => QQQ
[1] => XXXXXXXXXXXXXX
)
)
この例ではWWWWWWWWW
の変更を拾えませんでした。
得られる変更はcomputeChangeSets()
を呼び出した時点のものでした。
状態の取得
use App\Entities\Item;
use Doctrine\ORM\EntityManager;
/** @var EntityManager $manager */
$manager = require 'createManager.php';
$work = $manager->getUnitOfWork();
/** @var array<Item> $items */
$items = $manager->getRepository(Item::class)->findAll();
// IDが1と4のエンティティを変更
$items[0]->setPower(123);
$items[3]->setPower(456);
$items[3]->setName('QQQ');
// id = 2 を削除
$manager->remove($items[1]);
// id = 5 を外す
$manager->detach($items[4]);
// Add(StateはManagedになるがIdentiferMapには登録されない)
$addItem = new Item('XXX', 123);
$manager->persist($addItem);
// New(インスタンスを作っただけ)
$newItem = new Item('YYY', 456);
// 管理エンティティから変更を算出(このメソッドはflush()時にも呼び出さえれる)
$work->computeChangeSets();
echo " ==== [Insertions] \n";
print_r($work->getScheduledEntityInsertions());
echo " ==== [Deletions] \n";
print_r($work->getScheduledEntityDeletions());
echo " ==== [Updates] \n";
print_r($work->getScheduledEntityUpdates());
==== [Insertions]
Array
(
[86] => App\Entities\Item Object
(
[name:App\Entities\Item:private] => XXX
[power:App\Entities\Item:private] => 123
)
)
==== [Deletions]
Array
(
[90] => App\Entities\Item Object
(
[id:App\Entities\Item:private] => 2
[name:App\Entities\Item:private] => A
[power:App\Entities\Item:private] => 3
)
)
==== [Updates]
Array
(
[88] => App\Entities\Item Object
(
[id:App\Entities\Item:private] => 1
[name:App\Entities\Item:private] => F
[power:App\Entities\Item:private] => 123
)
[92] => App\Entities\Item Object
(
[id:App\Entities\Item:private] => 4
[name:App\Entities\Item:private] => QQQ
[power:App\Entities\Item:private] => 456
)
)
それぞれgetScheduledEntityInsertions()
は追加されたエンティティ、getScheduledEntityDeletions()
は削除されたエンティティ、getScheduledEntityUpdates()
は変更されたエンティティを取得できました。
$work->computeChangeSets();
ただしcomputeChangeSets()
よ呼び出してなかったら、追加または削除されたエンティティは取得出来ますが、変更されたエンティティは取得出来ません。