我有一个名为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?
答案 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事件,这些事件可以访问不仅仅是实体本身。
您应该查看DoctrineSluggableBundle或StofDoctrineExtensionsBundle个捆绑包,这些捆绑包可能会满足您的需求。