Symfony中Doctrine MongoDB Bundle的DocumentType字段关联报错排查
问题背景
我希望在MongoDB中实现文档间的关联引用,了解到Doctrine MongoDB Bundle提供了DocumentType表单类型,作用类似ORM中的EntityType,但官方文档仅提及该类型存在,未提供示例及详细说明。实现过程中先后遇到两个错误:
第一个错误:
Symfony\Bridge\Doctrine\Form\Type\DoctrineType::getCachedIdReader(): Argument #1 ($manager) must be of type Doctrine\Persistence\ObjectManager, null given, called in /var/www/clim_rep/vendor/symfony/doctrine-bridge/Form/Type/DoctrineType.php on line 199
调整实现方式后出现第二个错误:
"Doctrine MongoDB Manager named 'Doctrine\ODM\MongoDB\DocumentManager' does not exist"
以下是我编写的ReportType类代码:
<?php /** * ReportType - This class is responsible for creating the form for all Reports **/ declare(strict_types=1); namespace App\Form; use App\Document\Partner; use App\Document\Report; use App\Document\State; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\Event\PreSubmitEvent; use Doctrine\Bundle\MongoDBBundle\Form\Type\DocumentType; use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\Persistence\ObjectManager; /** * ReportType * This class is responsible for creating the form for the rental entity. **/ class ReportType extends AbstractType { /** * buildForm - This function is responsible for building the form for the rental entity. * * @param FormBuilderInterface $builder - The form builder interface * @param array $options - The options for the form */ public function buildForm(FormBuilderInterface $builder, array $options): void { $today = new \DateTime(); $builder ->add('name', TextType::class) ->add('date', TextType::class) ->add('author', TextType::class) ->add('report_type', TextType::class) ->add('description', TextType::class) ->add('partners', DocumentType::class, [ 'class' => Partner::class, 'choice_label' => 'name', 'expanded' => true, 'multiple' => true, 'document_manager' => DocumentManager::class, ]) // ->add('states', DocumentType::class, [ // 'class' => State::class, // 'choice_label' => 'name', // 'expanded' => true, // 'multiple' => true, // ]) ->add('dews_region', TextType::class) ->add('climate_region', TextType::class); } /** * configureOptions - This function is responsible for setting the default options for the form. * * @param OptionsResolver $resolver - The options resolver * */ public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults( [ 'data_class' => Report::class, 'entityManager' => null, ] ); } }
错误原因及修复方案
核心问题
- 第一个错误是因为DocumentType未获取到有效的DocumentManager实例,传入了null值。
- 第二个错误是因为
document_manager选项传入了类名(DocumentManager::class),但该选项需要的是DocumentManager实例或配置中定义的管理器名称(字符串,比如默认的default)。
修复步骤
移除错误的
document_manager配置:
若仅使用一个MongoDB DocumentManager,无需手动指定该选项,Bundle会自动注入默认管理器。若存在多个管理器,需传入管理器的配置名称(如'document_manager' => 'custom_mongo_manager'),而非类名。删除多余的
entityManager默认配置:
Form组件会自动处理Doctrine管理器的注入,configureOptions中设置的'entityManager' => null属于冗余配置,应移除。
修正后的代码
<?php /** * ReportType - This class is responsible for creating the form for all Reports **/ declare(strict_types=1); namespace App\Form; use App\Document\Partner; use App\Document\Report; use App\Document\State; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Doctrine\Bundle\MongoDBBundle\Form\Type\DocumentType; /** * ReportType * This class is responsible for creating the form for the rental entity. **/ class ReportType extends AbstractType { /** * buildForm - This function is responsible for building the form for the rental entity. * * @param FormBuilderInterface $builder - The form builder interface * @param array $options - The options for the form */ public function buildForm(FormBuilderInterface $builder, array $options): void { $today = new \DateTime(); $builder ->add('name', TextType::class) ->add('date', TextType::class) ->add('author', TextType::class) ->add('report_type', TextType::class) ->add('description', TextType::class) ->add('partners', DocumentType::class, [ 'class' => Partner::class, 'choice_label' => 'name', 'expanded' => true, 'multiple' => true, // 移除错误的document_manager配置 ]) ->add('states', DocumentType::class, [ 'class' => State::class, 'choice_label' => 'name', 'expanded' => true, 'multiple' => true, ]) ->add('dews_region', TextType::class) ->add('climate_region', TextType::class); } /** * configureOptions - This function is responsible for setting the default options for the form. * * @param OptionsResolver $resolver - The options resolver * */ public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults( [ 'data_class' => Report::class, // 移除多余的entityManager配置 ] ); } }
内容的提问来源于stack exchange,提问作者Tom Belknap

