2012-04-07 11 views
6

結果キャッシングを設定しようとしているリポジトリがあります。私はこれを行う方法についてオンラインで単一の例しか見つけることができませんでしたが、私のリポジトリの1つにこの例を実装するとエラーが発生します。 キャッシングにAPCを使用しており、config.ymlファイルでAPCを使用するためにクエリキャッシュを有効にしています。symfony2リポジトリでクエリ結果のキャッシュを指定する方法を教えてください。

class AchievementRepository extends EntityRepository 
{ 
    function findAchievementsByCategory($categoryObj) 
    { 
     $em=$this->getEntityManager()->createQuery("SELECT a FROM FTWGuildBundle:Achievement a where a.category=:category order by a.title") 
      ->setParameter('category',$categoryObj); 
     $em->useResultCache(true,3600,'findAchievementsByCategory'); 
     $result=$em->getResult(); 
     return $result; 
    } 
} 

そして、これが実行されたときに私が手に:私はここで私が持っているリポジトリのコードがあります(これの23Mは、この単一障害が発生したキャッシュエントリのためである)現在

をAPCに512Mを割り当てられ、その唯一の50Mを使用してきました次のエラー

Notice: apc_store() [<a href='function.apc-store'>function.apc-store</a>]: &quot;type&quot; returned as member variable from __sleep() but does not exist in /data/www/ftw2/Symfony/vendor/doctrine-common/lib/Doctrine/Common/Cache/ApcCache.php line 80 

私がキャッシュされているものを見るために私のapc.phpファイルで見ると、私は

の格納された値を持つユーザキャッシュセクションで私のキャッシュエントリを見つけます

誰かが私が間違っている場所についての指示を私に与えることはできますか?

このエンティティにはManyToOneという2つの列がありますが、これが機能するにはこのクエリで遅延ロードを無効にする必要がありますか?もしそうなら...どう? EDIT:に答えていない - ワーキングクラスコード(ノート、エンティティクラスのすべてのプロパティを:私はりんご:(

EDIT#2が...私のManyToOneマッピングへ= "EAGER" をフェッチ、追加することにより、熱心な負荷を有効にDoctrineはエンティティをキャッシュすると、保護に変更されました(達成))

class AchievementRepository extends EntityRepository 
{ 
    function findAchievementsByCategory($categoryObj) 
    { 
     $em=$this->getEntityManager()->createQuery("SELECT a FROM FTWGuildBundle:Achievement a where a.category=:category order by a.title") 
      ->setParameter('category',$categoryObj); 
     $em->useResultCache(true,3600,'findAchievementsByCategory'); 
     $result=$em->getArrayResult(); 
     return $result; 
    } 
} 

答えて

3

、それはそれのシリアル化された状態を保存します。問題は、民間の特性(教義によって生成されるデフォルトの可視性)をシリアライズすることはできません。に、ありますこの問題を解決するには、エンティティプロパティを保護する必要があります。詳細情報:http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-objects.html#merging-entities

もう1つはa know issueで、Symfony 2.1にあるDoctrineバージョン2.2で(最終的に)修正されました。何らかの理由でアップグレードできない場合は、関連付けをキャッシュする唯一の方法は、エンティティを移入する代わりにgetArrayResultを使用することです。

+0

ありがとうございます!保護されたプロパティを使用するように更新し、getResult()をgetArrayResult()に変更しました。これで正しくキャッシュされます。 – Chris

+0

@Chris、結果がキャッシュされたかどうかはどうでしたか? – cbacelar

+0

@cbacelar - いくつかの方法 1)クエリデバッガを使用して、ページをレンダリングし、いくつのクエリが実行されているかを確認します。ここにキャッシュされていないクエリが表示されます。ページを更新すると、キャッシュされたクエリは実行されません。 2)キャッシュ(memcached、apcなど)の統計情報を確認して、より多くのデータまたはそれ以上のレコードがキャッシュにあるかどうかを確認します。 apcには、キャッシュ内の各エンティティ(キー、値、統計情報など)を表示できるようにインストールできる素晴らしいインターフェイスがあります。 – Chris

関連する問題