如何从实体获取存储库?

时间:2011-09-17 21:24:53

标签: doctrine-orm symfony

我有一个名为Game的实体,其中包含一个名为GameRepository的相关存储库:

/**
 * @ORM\Entity(repositoryClass="...\GameRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Game {
    /**
     * @ORM\prePersist
     */
    public function setSlugValue() {
        $this->slug = $repo->createUniqueSlugForGame();
    }
}

在prePersist方法中,我需要确保Game的slug字段是唯一的,这需要数据库查询。要进行查询,我需要访问EntityManager。我可以从GameRepository中获取EntityManager。那么:如何从游戏中获取GameRespository?

4 个答案:

答案 0 :(得分:55)

您实际上可以获取实体中的存储库,并且仅在生命周期回调期间获取存储库。你非常接近它,你所要做的就是接收LifecycleEventArgs参数。

另见http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html

use Doctrine\ORM\Event\LifecycleEventArgs;

/**
 * @ORM\Entity(repositoryClass="...\GameRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Game {
    /**
     * @ORM\prePersist
     */
    public function setSlugValue( LifecycleEventArgs $event ) {
        $entityManager = $event->getEntityManager();
        $repository    = $entityManager->getRepository( get_class($this) );

        $this->slug = $repository->createUniqueSlugForGame();
    }
}

PS。我知道这是一个老问题,但我回答它是为了帮助任何未来的googlers。

答案 1 :(得分:8)

你没有。 Doctrine 2中的实体应该知道实体管理器或存储库。

您提供的案例的典型解决方案是向存储库(或服务类)添加一个方法,该方法用于创建(或调用存储)新实例,并且还会生成唯一的slug值。

答案 2 :(得分:4)

您可以在您的实体中注入教义实体管理器 (使用JMSDiExtraBundle) 并拥有这样的存储库:

/**
 * @InjectParams({
 *     "em" = @Inject("doctrine.orm.entity_manager")
 * })
 */
    public function setInitialStatus(\Doctrine\ORM\EntityManager $em) {


    $obj = $em->getRepository('AcmeSampleBundle:User')->functionInRepository();
    //...
}

请参阅:http://jmsyst.com/bundles/JMSDiExtraBundle/1.1/annotations

答案 3 :(得分:1)

为了保持逻辑封装而不必更改保存实体的方式,而不是简单的prePersist生命周期事件,您将需要查看使用更强大的Doctrine事件,这些事件可以访问不仅仅是实体本身。

您应该查看DoctrineSluggableBundleStofDoctrineExtensionsBundle个捆绑包,这些捆绑包可能会满足您的需求。