Symfony 2 UniqueEntity repositoryMethod 在更新实体时失败

我正在编写一些简单的脚本,但无法解决这个问题.所以就是这里了.

I'm working on some simple script, but can't wrap my head around this problem. So here it is.

/**
 * Booking
 * @ORMTable()
 * @ORMEntity(repositoryClass="TonsBookingBundleEntityBookingRepository")
 * @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
 * @AssertCallback(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();
    }

问题是这适用于它应该的创建方法,但是当更新现有实体时 - 它违反了这个限制.

The problem is that this works on create methods like it should, but when updating existing entity - it violates this constrain.

我尝试添加Id约束,但是在创建实体时,id为null,因此repository Method甚至没有启动.我也尝试删除实体,然后重新创建它.喜欢

I tried to add Id constrain, but when creating entities, id is null, so repository Method don't even starts. Also i tried to remove Entity and then recreate it. like

$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(),
        );
    }

推荐答案

我明白了!我把注释改成了这个

I got this! I changed annotation to this

/**
 * Booking
 * @ORMTable()
 * @ORMEntity(repositoryClass="TonsBookingBundleEntityBookingRepository")
 * @UniqueEntity(fields={"id","room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
 * @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings",groups={"create"})
 * @AssertCallback(methods={"isSinceLessThanTill"}, groups={"search","default"})
 */
class Booking

将 BookingType 复制到 BookingTypeCreate 并添加

Copy BookingType to BookingTypeCreate And added

 public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TonsBookingBundleEntityBooking',
            'validation_groups' => array('create'),
        ));
    }

形成默认值.所以现在将实体传递给验证方法时参数是不同的.我认为这仍然是一种解决方法.

To form defaults. So now parameters are different when passing entity to validation method. I think it's still a workaround method.

相关文章