【问题标题】:Embedded form entity is not persisted嵌入的表单实体未持久化
【发布时间】:2015-06-19 05:15:14
【问题描述】:

Symfony 2.6.9

我有具有avatar 属性的UserProfile 实体,该属性具有oneToOneUserAvatar 实体的单向关系和级联持久性。

BlogBundle\Entity\UserProfile:
    type: entity
    table: user_profiles
    id:
        id:
            type: integer
            generator:
                strategy: AUTO
    fields:
        #...
    oneToOne:
        #...
        avatar:
            targetEntity: UserAvatar
            cascade: ['persist', 'remove']

我创建了带有嵌入式头像表单字段的UserProfile 表单类型:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            #...
            ->add('avatar', new UserAvatarType, [
                'required' => false,
            ])
            ->add('submit', 'submit', [
                'attr' => [
                    'class' => 'right'
                ]
            ])
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'BlogBundle\Entity\UserProfile',
            'cascade_validation' => true,
        ));
    }

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

还有UserAvatarType:

class UserAvatarType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file', 'file', [
                'label' => false
            ])
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'BlogBundle\Entity\UserAvatar',
        ));
    }

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

UserProfileUserAvatar 实体在我提交表单时已经存在,它们是在用户注册持久性事件时自动创建的。我只是编辑个人资料实体。

当我提交表单时,UserProfile 内的所有字段都保存得很好,但没有嵌入avatar 字段。未调用 UserProfile 内的方法 setAvatarUserAvatar 的验证顺利通过。没有错误,UserAvatar 实体只是没有持久化。

Gist.

有人可以帮忙吗?

【问题讨论】:

    标签: symfony


    【解决方案1】:

    我只能猜测,但在控制器级别会犯一个非常常见的错误。确保你有类似的东西:

    $profile = new UserProfile();
    $avatar = new UserAvatar();
    $profile->setAvatar($avatar);
    
    $form = $this->createForm(new UserProfileType(), $profile)
    

    然后像你已经做的那样处理你的表单。

    希望这会有所帮助。

    编辑

    鉴于 cmets 中给出的英特尔,问题已完全确定:用户对象被延迟加载,Doctrine 无法持续​​存在。我会做的是:

    • 在您的 UserController 中,在 profileEditAction() 中,当 $user 由对 findOneByUsername($username) 的调用定义时,您从 UserRepository 调用您自己的方法(随便命名,比如说 findOneByUsernameCustom),我们正在创作。
    • 转到您的 UserRepository 并创建此自定义方法。它应该是这样的:

      public function findOneByUsernameCustom(){
      
      $em = $this->getEntityManager();
      $qb = $em->createQueryBuilder();
      $qb
          ->select('User','firstUserProperty','secondUserProperty')
          ->from('AppBundle\Entity\User','User')
          ->leftJoin('User.firstUserProperty','fistUserProperty')
          ->leftJoin('User.secondUserProperty','secondUserProperty')
          ;
      $q = $qb->getQuery();
      return $q->getResult();}
      

    基本上 leftJoin 加入你的用户的每一个属性,这样当你从数据库中检索你的用户时,它就会正确地完成。

    您可以阅读这篇出色的article 了解更多详情。

    【讨论】:

    • UserProfileUserAvatar 实体在用户注册时自动创建。在控制器中,我只检查验证并持久化/刷新UserProfile 实体。由于cascade: ['persist'] 选项,我希望UserAvatar 自动持久化。
    • 也许我错了,但你确定你的 $profile 有一个 $avatar 吗?也许转储 $profile 看看是什么...
    • 为什么没有控制器?从这个存储库中很难确定任何事情......
    • 添加了UserControllerUser 实体。
    • 您的控制器的第 108 行,您可以转储 $user 变量并发布其内容吗?
    【解决方案2】:

    我最终发现了问题所在。

    如果没有更改的映射字段,实体将不会被持久化。在我的情况下,我只更改文件字段,它是虚拟字段并且没有映射到数据库。

    以下是文档中有关此问题的一些信息:

    PreUpdatePostUpdate 回调仅在实体的一个持久化字段发生更改时触发。这意味着,默认情况下,如果您只修改 $file 属性,这些事件将不会被触发,因为属性本​​身不是通过 Doctrine 直接持久化的。一种解决方案是使用持久化到 Doctrine 的更新字段,并在更改文件时手动修改它。

    这是我们可以解决的方法。我们可以创建一些虚拟字段,在setFile() 调用时会更改:

    <?php
    public function setFile(UploadedFile $file)
    {
        $this->file = $file;
        $this->createdAt = new \DateTime;
    }
    ?>
    

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 2016-03-28
      • 2013-01-10
      相关资源
      最近更新 更多