Мне нужна помощь с обновлением отношений с первого лица в 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'
Хорошо, я понимаю, что он хочет вставить новую запись, но что я должен сделать, чтобы сделать его ОБНОВЛЕНИЕ или УДАЛИТЬ существующую и ВСТАВИТЬ новую.
Попробуйте сделать 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;
}
Вам нужно использовать 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;