Symfony 2 UniqueEntity repositoryMethod не работает при обновлении объекта

Я работаю над некоторым простым скриптом, но не могу оборачивать эту проблему. Так вот оно.

/** * Booking * @ORM\Table() * @ORM\Entity(repositoryClass="Tons\BookingBundle\Entity\BookingRepository") * @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings") * @Assert\Callback(methods={"isSinceLessThanTill"}, groups={"search","default"}) */ class Booking 

и метод репозитория

 /** * Get room state for a certain time period * * @param array $criteria * @return array */ public function getInterferingRoomBookings(array $criteria) { /** @var $room Room */ $room = $criteria['room']; $builder = $this->getQueryForRoomsBooked($criteria); $builder->andWhere("ira.room = :room")->setParameter("room", $room); return $builder->getQuery()->getArrayResult(); } 

Проблема в том, что это работает над созданием подобных методов, но при обновлении существующей сущности – это нарушает это ограничение.

Я попытался добавить Id constrain, но при создании сущностей id равен null, поэтому метод репозитория даже не запускается. Также я попытался удалить Entity, а затем воссоздал его. как

 $em->remove($entity); $em->flush(); //----------- $em->persist($entity); $em->flush(); 

но это также не работает.

Создать действие

  /** * Creates a new Booking entity. * * @Route("/create", name="booking_create") * @Method("POST") * @Template("TonsBookingBundle:Booking:new.html.twig") */ public function createAction(Request $request) { $entity = new Booking(); $form = $this->createForm(new BookingType(), $entity); $form->bind($request); if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $room = $entity->getRoom(); if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId()) { $entity->setCreatedAt(new \DateTime()); $entity->setUpdatedAt(new \DateTime()); $entity->setManager($this->getUser()); $em->persist($entity); $room->setLocked(false); $room->setLockedBy(null); $room->setLockedAt(null); $em->persist($room); $em->flush(); return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId()))); } else { $form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером")); return array( 'entity' => $entity, 'form' => $form->createView(), ); } } return array( 'entity' => $entity, 'form' => $form->createView(), ); } 

Обновить действие

  /** * Edits an existing Booking entity. * * @Route("/edit/{id}/save", name="booking_update") * @Method("PUT") * @Template("TonsBookingBundle:Booking:edit.html.twig") */ public function updateAction(Request $request, $id) { /** @var $em EntityManager */ $em = $this->getDoctrine()->getManager(); $entity = $em->getRepository('TonsBookingBundle:Booking')->find($id); if (!$entity) { throw $this->createNotFoundException('Unable to find Booking entity.'); } $editForm = $this->createForm(new BookingType(), $entity); $editForm->bind($request); if ($editForm->isValid()) { $em->persist($entity); $em->flush(); return $this->redirect($this->generateUrl('booking_edit', array('id' => $id))); } return array( 'entity' => $entity, 'form' => $editForm->createView(), ); } 

Solutions Collecting From Web of "Symfony 2 UniqueEntity repositoryMethod не работает при обновлении объекта"

Я получил это! Я изменил аннотацию к этому

 /** * Booking * @ORM\Table() * @ORM\Entity(repositoryClass="Tons\BookingBundle\Entity\BookingRepository") * @UniqueEntity(fields={"id","room", "since", "till"}, repositoryMethod="getInterferingRoomBookings") * @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings",groups={"create"}) * @Assert\Callback(methods={"isSinceLessThanTill"}, groups={"search","default"}) */ class Booking 

Копировать BookingType в BookingTypeCreate и добавлено

  public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Tons\BookingBundle\Entity\Booking', 'validation_groups' => array('create'), )); } 

Формирование значений по умолчанию. Таким образом, теперь параметры различаются при передаче объекта методу проверки. Я думаю, что это все же метод обхода.

Краткий ответ: вы не получаете данные формы в сущности, поэтому вы работаете с новым сущностью, которая не знает, что ее комната установлена ​​в форме.

Длинный ответ: получение данных формы и их размещение в сущности позволяет вам манипулировать данными перед обновлением. См. Измененный контроллер ниже. Ключевая строка

$entity = form->getData(); Что затем позволяет вам $room=$entity->getRoom();

 /** * Creates a new Booking entity. * * @Route("/create", name="booking_create") * @Method("POST") * @Template("TonsBookingBundle:Booking:new.html.twig") */ public function createAction(Request $request) { $entity = new Booking(); $form = $this->createForm(new BookingType(), $entity); $form->bind($request); $entity = $form->getData(); // Lighthart's addition if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $room = $entity->getRoom(); if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId()) { $entity->setCreatedAt(new \DateTime()); $entity->setUpdatedAt(new \DateTime()); $entity->setManager($this->getUser()); $em->persist($entity); $room->setLocked(false); $room->setLockedBy(null); $room->setLockedAt(null); $em->persist($room); $em->flush(); return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId()))); } else { $form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером")); return array( 'entity' => $entity, 'form' => $form->createView(), ); } } return array( 'entity' => $entity, 'form' => $form->createView(), ); } 

Передайте дополнительный идентификатор (возможно, token ) в уникальное поле проверки (например, loginName ) ( fields={"token", "loginName"} ) в метод repositoryMethod. Сам id не работает, он равен нулю при создании объекта, и метод repositoryMethod не выполняется. Я создаю token в методе конструктора. Маркер необходим для идентификации объекта при создании или обновлении.

 /** * @ORM\Table(name="anbieterregistrierung") * @ORM\Entity(repositoryClass="AnbieterRegistrierungRepository") * @UniqueEntity( * fields={"token", "loginName"}, * repositoryMethod="findUniqueEntity" * ) */ 

то в классе репозитория вы редактируете WHERE DQL:

 public function findUniqueEntity(array $parameter) { $loginName = $parameter['loginName']; $token = $parameter['token']; . . . . . . WHERE anbieterregistrierung.loginName = :loginName AND anbieterregistrierung.token <> :token . . . }