疑难解答“必须管理传递到选择字段的实体”

时间:2012-08-21 14:04:07

标签: forms symfony

这个问题在SO上被多次询问 - 每次,解决方案看起来都不同,而且几乎总是,答案似乎是偶然发现的/或者是粗暴的黑客 - 意味着没有关于导致问题的原因以及如何解决问题的一致看法。

我也遇到消息“必须管理传递给选择字段的实体” - 并且不清楚为什么会引发此异常。

我在一个包中定义了一个Contact类(.yml格式)。 Contact类与另外两个类PromotionContactReferrer有一个manyToOne关系 - 见下文:

Foobar\ContactlistBundle\Entity\Contact:
    type: entity
    table: contact
    repositoryClass: Foobar\ContactlistBundle\Repository\ContactRepository

    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        first_name:
            type: string
            length: 32
            nullable: true

        last_name:
            type: string
            length: 64
            nullable: true

        email:
            type: string
            length: 128
            unique: true

        token:
            type: string
            length: 8
            unique: true

        is_validated:
            type: boolean

        created_at:
            type: datetime

        updated_at:
            type: datetime
            nullable: true


    manyToOne:
        promotion:
            targetEntity: Promotion
            inversedBy: promoted_contacts
            joinColumn:
                name: promotion_id
                referencedColumnName: id

        referrer:
            targetEntity: ContactReferrer
            inversedBy: referrer_contacts
            joinColumn:
                name: contact_referrer_id
                referencedColumnName: id

我使用php app/console doctrine:generate:form FooBarContaclistBundleContact生成了表单,并按如下方式手动编辑了表单:

class ContactType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('first_name')
            ->add('last_name')
            ->add('email', 'email')
            ->add('token')
            ->add('is_validated')
            ->add('created_at')
            ->add('updated_at')
            ->add('promotion', 'entity', array(
                                                'class' => 'Foobar\ContactlistBundle\Entity\Promotion',
                                                'expanded' => false,
                                                'multiple' => false, )
                 )
            ->add('referrer', 'entity', array(
                                                'class' => 'Foobar\ContactlistBundle\Entity\ContactReferrer',
                                                'expanded' => false,
                                                'multiple' => false, )
            );
    }

    public function getName()
    {
        return 'Foobar_contactlistbundle_contacttype';
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Foobar\ContactlistBundle\Entity\Contact',
        );
    }
}

在我的Entity / Contact.php类中,这是构造函数的代码:

class Contact
{
    public function __construct()
    {
        $this->token = 'abcdef123';
        $this->is_validated = false;
        $this->created_at =  new \DateTime();
        $this->setUpdatedAt(new \DateTime());

        // Set these to defaults
        $this->promotion = new \Foobar\ContactlistBundle\Entity\Promotion();
        $this->referrer = new \Foobar\ContactlistBundle\Entity\ContactReferrer();
    }

    // more code ... 
}

在我的控制器中,我有以下代码:

public function newcontactAction(Request $request)
{
    // do something ...
    $contact = new Contact();
    $form = $this->createForm(new ContactType(), $contact);  // <- Exception thrown here
    // do something ...
}

当我浏览导致上述控制器代码执行的路线时,我收到错误:Entities passed to the choice field must be managed - 任何人是否知道造成这种情况的原因以及如何解决?< / p>

1 个答案:

答案 0 :(得分:5)

Entities passed to the choice field must be managed表示必须将相关实体持久保存到entityManager。在创建表单

之前,请尝试保留promotionreferrer个实体
public function newcontactAction(Request $request)
{
    // do something ...
    $em->persist($contact->getPromotion());
    $em->persist($contact->getReferrer());
    $form = $this->createForm(new ContactType(), $contact);

如果这没有帮助,则必须创建新的促销和引用实体,将它们保留到entityManager,而不是flush()。只有在此步骤之后,才能创建新的联系人实体并创建表单。