DoctrineとEloquentの相違点

主にSymfonyで用いられているORMのDoctrineと、主にLaravelで用いられているORMのEloquentですが、両方使ってみて明確な違いを一つ見つけたので、まとめました。

Doctrineの場合

$entity = new Entity();

// モデルを保存
$entityManager->persist($entity);
$entityManager->flush();

// 作成したモデルのidでDBから検索
$fetched = $entityRepository->find($entity->getId());

var_dump($entity === $fetched); // trueになる

Eloquentの場合

$model = Model::create();

$fetched = Model::find($model->id);

var_dump($model === $fetched); // falseになる

コードをみてもらうとわかる通り、Doctrineでは同じプライマリーキーを持つエンティティは必ず同一インスタンスになります。(後述の例外を除いて)

対して、Eloquentでは同じプライマリーキーを持っていても同一インスタンスになるとは限らないです。

これは、Repositoryパターンとして実装されているDoctrineとActiveRecordで実装されているEloquentの設計思想から生まれる物だと思います。

EloquentではmodelはDBからデータを取得するための便利機能の詰め合わせであり、同じプライマリーキーを持っていても、それはたまたまそうなっただけである、という扱いなのだと思います。

DoctrineではEntityと銘打っている通り、「実体」としてオブジェクトが存在し、同じプライマリーキーを持つなら、必ず同じ実体として存在する必要がある、という立場を取っているのだと思います。

そのため、Entityをsessionなどにいれると、同じプライマリーキーなのに別のインスタンスができてしまい、それをDBに登録しようとするとエラーになります。

このエラーはある程度書けるようになった初心者がよくハマる所(体験談)ですが、このように別のORMと比較しながら、Doctirneの設計思想を考えて行くとすんなり理解できるようなしないような。。。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です