Обновление формы Symfony2 один к одному

Мне нужна помощь с обновлением отношений с первого лица в Symfony2. У меня есть лица: User и UserInfo

Пользовательский объект:

class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
* @ORM\JoinTable(name="fos_user_user_group",
*      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
*      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;

/**
* @ORM\OneToOne(targetEntity="UserInfo", mappedBy="user", cascade={"all"})
*/
private $info;

/**
* @ORM\OneToMany(targetEntity="Log", mappedBy="user")
*/
private $logs;

public function __construct()
{
parent::__construct();
$this->logs = new ArrayCollection();
}

/**
* Set info
*
* @param \AppBundle\Entity\UserInfo $info
* @return User
*/
public function setInfo(\AppBundle\Entity\UserInfo $info = null)
{
$this->info = $info;
$info->setUser($this);

return $this;
}

/**
* Get info
*
* @return \AppBundle\Entity\UserInfo
*/
public function getInfo()
{
return $this->info;
}

/**
* Add logs
*
* @param \AppBundle\Entity\Log $logs
* @return User
*/
public function addLog(\AppBundle\Entity\Log $logs)
{
$this->logs[] = $logs;

return $this;
}

/**
* Remove logs
*
* @param \AppBundle\Entity\Log $logs
*/
public function removeLog(\AppBundle\Entity\Log $logs)
{
$this->logs->removeElement($logs);
}

/**
* Get logs
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getLogs()
{
return $this->logs;
}
}

Объект UserInfo:

class UserInfo
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var string
*
* @ORM\Column(name="position", type="string", length=255)
*/
private $position;

/**
* @var string
*
* @ORM\Column(name="info", type="text")
*/
private $info;

/**
* @var string
*
* @ORM\Column(name="fullname", type="string", length=255)
*/
private $fullname;

/**
* @ORM\OneToOne(targetEntity="User", inversedBy="info")
*/
private $user;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set position
*
* @param string $position
* @return UserInfo
*/
public function setPosition($position)
{
$this->position = $position;

return $this;
}

/**
* Get position
*
* @return string
*/
public function getPosition()
{
return $this->position;
}

/**
* Set info
*
* @param string $info
* @return UserInfo
*/
public function setInfo($info)
{
$this->info = $info;

return $this;
}

/**
* Get info
*
* @return string
*/
public function getInfo()
{
return $this->info;
}

/**
* Set fullname
*
* @param string $fullname
* @return UserInfo
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;

return $this;
}

/**
* Get fullname
*
* @return string
*/
public function getFullname()
{
return $this->fullname;
}

/**
* Set user
*
* @param \AppBundle\Entity\User $user
* @return UserInfo
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;

return $this;
}

/**
* Get user
*
* @return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
}

Это их типы:

class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('password')
->add('info', new UserInfoType(), [
'by_reference' => false,
])
->add('Submit', 'submit')
;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\User',
]);
}

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

а также

class UserInfoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('position')
->add('info')
->add('fullname')
;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\UserInfo',
'allow_delete' => true,
]);
}

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

Новая запись вставляется без проблем, но когда я хочу обновить эту запись с помощью этого действия:

public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();

$userRepository = $em->getRepository('AppBundle:User');

$user = $userRepository->findOneBy(['id' => $id]);

$form = $this->createForm(new UserType(), $user);

$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$em->persist($user);
$em->flush();

return $this->redirectToRoute('user_list');
}

return $this->render('@App/User/form.html.twig', [
'form' => $form->createView(),
]);
}

Я получаю эту ошибку:

An exception occurred while executing 'INSERT INTO user_info (position, info, fullname, user_id) VALUES (?, ?, ?, ?)' with params ["321", "321", "321", 14]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '14' for key 'UNIQ_B1087D9EA76ED395'

Хорошо, я понимаю, что он хочет вставить новую запись, но что я должен сделать, чтобы сделать его ОБНОВЛЕНИЕ или УДАЛИТЬ существующую и ВСТАВИТЬ новую.

2

Решение

Попробуйте сделать User владеющая сторона и UserInfo обратный (см. документы).

class User extends BaseUser
{
/**
* @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"})
*/
private $info;
}

class UserInfo
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\OneToOne(targetEntity="User", mappedBy="info")
*/
private $user;
}

Также связано с этот ТАК вопрос.

Редактировать: Удалить старый, не имеющий ссылки UserInfo записи после обновления, установите orphanRemoval вариант в info собственность User учебный класс.

class User extends BaseUser
{
/**
* @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"}, orphanRemoval=true)
*/
private $info;
}
3

Другие решения

Вам нужно использовать JoinColumn аннотации в вашем User учебный класс:

/**
* @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"})
* @ORM\JoinColumn(name="info", referencedColumnName="id")
*/
private $info;

UserInfo:

/**
* @ORM\OneToOne(targetEntity="User", mappedBy="info")
*/
private $user;
0

По вопросам рекламы [email protected]