Symfony 2.6.9
我的UserProfile
实体具有avatar
属性,与oneToOne
实体和级联持久性具有UserAvatar
单向关系。
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';
}
}
我提交表单时已经存在 UserProfile
和UserAvatar
个实体,它们是在用户注册持久性事件时自动创建的。我只是编辑个人资料实体。
当我提交表单时,UserProfile
中的所有字段都会保留良好,但不会嵌入avatar
字段。未调用setAvatar
内的方法UserProfile
。 UserAvatar
上的验证通过良好。没有错误,UserAvatar
实体没有持久存在。
有人可以帮忙吗?
答案 0 :(得分:0)
我只能猜测,但是在控制器级别犯了一个非常常见的错误。确保你有类似的东西:
$profile = new UserProfile();
$avatar = new UserAvatar();
$profile->setAvatar($avatar);
$form = $this->createForm(new UserProfileType(), $profile)
然后像你一样处理你的表格。
希望这有帮助。
修改
鉴于注释中提供了intel,问题已完全识别:用户对象被延迟加载,Doctrine无法继续存在。我会做的是:
$user
来定义findOneByUsername($username)
时,你可以从UserRepository中调用你自己的方法(将它命名为你想要的任何东西,让&#39 ; s say 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();}
Basicaly leftJoin用户的每个属性,以便当您从数据库中检索用户时,它将正确完成。
有关详细信息,请参阅此优秀article。
答案 1 :(得分:0)
我最终发现了问题所在。
如果没有更改的映射字段,实体将不会保留。在我的情况下,我只更改文件字段,它是虚拟字段,而不是映射到数据库。
以下是文档中有关此问题的一些信息:
PreUpdate
和PostUpdate
回调只有在其中一个实体的字段中存在持续变化时才会触发。这意味着,默认情况下,如果仅修改$file
属性,则不会触发这些事件,因为属性本身不会通过Doctrine直接保留。一种解决方案是使用持久保存到Doctrine的更新字段,并在更改文件时手动修改它。
以下是我们如何解决它。我们可以创建一些虚拟字段,在setFile()
调用时将更改:
<?php
public function setFile(UploadedFile $file)
{
$this->file = $file;
$this->createdAt = new \DateTime;
}
?>