Symfony中@ParamConverter注解异常排查求助
Symfony未使用@ParamConverter却触发"App\Entity\Recipe object not found"错误的排查与解决
问题场景
调用控制器方法时出现错误:
App\Entity\Recipe object not found by the @ParamConverter annotation
但控制器方法并未使用@ParamConverter注解,相关代码如下:
RecipeRepository中的方法
function findPublicRecipe(?int $nbRecipes): array { $queryBuilder = $this->createQueryBuilder('r') ->where('r.isPublic = 1') ->orderBy('r.createdAt', 'DESC'); if ($nbRecipes !== 0 && $nbRecipes !== null) { $queryBuilder->setMaxResults($nbRecipes); } return $queryBuilder->getQuery()->getResult(); }
控制器方法
#[Route('/recipe/public', name: 'recipe.index.public', methods: ['GET'])] public function indexPublic( RecipeRepository $repository, Request $request, PaginatorInterface $paginator, ): Response { $recipes = $repository->findPublicRecipe(null); $recipes = $paginator->paginate( $recipes, $request->query->getInt('page', 1), 10 ); return $this->render('pages/recipe/indexPublic.html.twig', [ 'recipes' => $recipes ]); }
已确认Recipe实体导入、命名空间、实体注解均无问题,仍触发该错误。
可能原因与解决方案
1. 路由缓存过期
Symfony会缓存路由配置,若之前该路由或控制器存在使用@ParamConverter的历史配置,缓存未清除会导致旧规则生效。
- 执行缓存清除命令:
生产环境需添加环境参数:php bin/console cache:clearphp bin/console cache:clear --env=prod
2. 路由匹配冲突
存在其他带占位符的路由(如/recipe/{recipe}或/recipe/{slug}),其匹配优先级高于当前固定路径路由,导致Symfony尝试将public作为占位符参数,通过@ParamConverter转换为Recipe实体,最终触发找不到对象的错误。
- 执行命令查看所有路由规则,检查是否存在冲突:
php bin/console debug:router - 若存在冲突,可通过以下方式解决:
- 调整路由顺序:将固定路径的路由(
/recipe/public)放在带占位符的路由之前; - 为带占位符的路由添加约束(如
#[Route('/recipe/{slug<[a-z0-9-]+>}', ...)]),避免匹配public这类特殊路径; - 修改冲突路由的路径,避免与固定路径重叠。
- 调整路由顺序:将固定路径的路由(
3. 控制器类或方法的隐性配置问题
- 检查控制器类是否存在全局的
@ParamConverter注解(类级别的注解会作用于所有方法); - 确认控制器方法的参数列表中,是否不小心注入了
Recipe实体(即使代码中没写,可能存在误删或版本控制的旧代码残留); - 检查路由名称是否重复:其他控制器方法是否使用了
recipe.index.public这个名称,导致路由规则混乱。
4. 分页组件的隐性触发
若使用的是KnpPaginator等分页组件,确认传递给paginate()的是数组而非QueryBuilder实例(用户当前代码已正确传递数组,此情况概率较低)。若之前传递的是QueryBuilder,缓存未清除可能导致组件尝试进行额外的实体转换操作。
内容的提问来源于stack exchange,提问作者nabil lambattan
相关产品推荐
相关产品推荐

