Symfony2標準のDocrine2がクエリを投げるとき、
Entityで外部参照のものがあるときなどで
Entity本体でなくてProxyというオブジェクトが代わりに返ってくるのは、
パフォーマンスのための柔軟性としてそう設計されている、と言いつつ、
気づかないで結構へんな詰まり方をしてしまう。
通常はinner joinを使うことで回避できて、
それは呼び出し側が外部キーのカラムを明示的に持っていればSQLとしてそう書けるのだが、
私がやりたいケースでは、
mappedByという形でアノテーション指定している側()が呼び出し側になってしまい、
そのエンティティだけを読んだ時に全部呼びたいのに、
やっぱりProxyが代わりに読まれてしまうという問題に出くわした。
解決策としては、最終的な処理で初めて全てのSQLが走って本物のオブジェクトが得られるlazy loadではなくて、最初から読むeagerにすれば良い、はずなのだが、
Entityのアノテーション属性のfetchにEAGERと指定する方法
と、
EntityManagerのfetchModeを"EAGER"とする方法
があるようで、
そもそもentityにアノテーションで書いてある場合には、
前者のほうがすっきりするようだった。
もちろん、その分遅くなってしまうというのはあると思うが、
今のところ私の扱っているエンティティは
レコード数、更新はそれほどないようなので、
とりあえずこれで様子を見てみようと思う。
Entityで外部参照のものがあるときなどで
Entity本体でなくてProxyというオブジェクトが代わりに返ってくるのは、
パフォーマンスのための柔軟性としてそう設計されている、と言いつつ、
気づかないで結構へんな詰まり方をしてしまう。
通常はinner joinを使うことで回避できて、
それは呼び出し側が外部キーのカラムを明示的に持っていればSQLとしてそう書けるのだが、
私がやりたいケースでは、
mappedByという形でアノテーション指定している側()が呼び出し側になってしまい、
そのエンティティだけを読んだ時に全部呼びたいのに、
やっぱりProxyが代わりに読まれてしまうという問題に出くわした。
解決策としては、最終的な処理で初めて全てのSQLが走って本物のオブジェクトが得られるlazy loadではなくて、最初から読むeagerにすれば良い、はずなのだが、
Entityのアノテーション属性のfetchにEAGERと指定する方法
と、
EntityManagerのfetchModeを"EAGER"とする方法
があるようで、
そもそもentityにアノテーションで書いてある場合には、
前者のほうがすっきりするようだった。
もちろん、その分遅くなってしまうというのはあると思うが、
今のところ私の扱っているエンティティは
レコード数、更新はそれほどないようなので、
とりあえずこれで様子を見てみようと思う。
コメント
コメントを投稿