EntityManager已关闭?

问题描述 投票:1回答:1

我在第167行得到错误它告诉我EntityManager已关闭?我用过symfony2和aurelia。我把“processUserDetails”放进去了。

 private function processUserDetails($library, $entity, $oldDetails, $settings) {
        $newDetails = $entity->getDetails();
        $em = $this->getDoctrine()->getManager();

        $this->disableBlameableEventListeners($em);

        foreach($oldDetails as $detail) {
            if(!$newDetails->contains($detail)) {
                $library->removeResource($detail->getResource());
                $em->remove($detail);
            }
        }

        $em->flush();
        $this->enableBlameableEventListeners($em);

        foreach($newDetails as $detail)
            if(!$detail->getId()) $em->persist($detail);

        $em->flush();

        foreach($newDetails as $detail) {
            $resource = $detail->getResource();

            if(!$library->getResources()->contains($resource))
                $library->addResource($resource);
        }
        $em->flush();
        if($this->getUser() === $entity->getUser()) {
            $this->putMembershipContactSetting($entity, $settings);
            $locale = $entity->getLocale();

            if($locale && $entity->getUser()->getLocale() !== $locale)
                $this->setUserLocale($entity);

            $em->flush();
        }
    }

 public function putMembershipAction(Request $request, Company $company, Membership $entity) {
        if(!$this->canTouchIt($company, 'RolesManage') && $this->getUser() !== $entity->getUser())
            return FOSView::create('Unauthorized', Codes::HTTP_UNAUTHORIZED);

        $em = $this->getDoctrine()->getManager();
        $settings = $request->request->get('contact_settings');

        $request->setMethod('PATCH');
        $library = $entity->getAssets();

        $form = $this->createForm(
            new MembershipType($this->isAdminUser()), $entity,
            array('method' => $request->getMethod())
        );

        $oldDetails = $entity->getDetails();
        $entity->setDetails(new ArrayCollection);

        $this->removeExtraFields($request, $form);
        $form->handleRequest($request);



        if($form->isValid()) {

            if($entity->getPermissions())
                $entity->getPermissions()->setMembership($entity);

            if($entity->getStatus() === Membership::STATUS_ACCEPTED)
                $this->processUserDetails($library, $entity, $oldDetails, $settings);

            $this->get('desygner_brand.membership.manager')
                ->addMemberToGlobalGroup($entity);

            $serializer = $this->get('jms_serializer');
            $context = SerializationContext::create()->setGroups(array('membership'));
            $this->get('monolog.logger.behaviour')->error('Company log #'.$company->getId(), array(
                'type' => 'Modify memeber',
                'user' => $this->getUser()->getId(),
                'data' => json_decode($this->get('jms_serializer')
                    ->serialize($entity, 'json', $context), true
                ),
            ));

            return $entity;
        }

        return FOSView::create(array('errors' => $form->getErrors()), Codes::HTTP_PRECONDITION_FAILED);
    }

enter image description here

我在第167行得到错误它告诉我EntityManager已关闭?我也使用了symfony2和aurelia,我把“processUserDetails”用于浏览它。

可以帮我吗?

aurelia symfony-2.1
1个回答
1
投票

你在processUserDetails太早了。它需要重构方法/类以确保在适当的时候调用flush()。一个快速解决方法是让方法接受EntityManager作为参数,并使用一个可选参数来告诉它不要在结尾处刷新:

private function processUserDetails($em, $library, $entity, $oldDetails, $settings, $doNotFlush) {
    $newDetails = $entity->getDetails();

    $this->disableBlameableEventListeners($em);

    foreach($oldDetails as $detail) {
        if(!$newDetails->contains($detail)) {
            $library->removeResource($detail->getResource());
            $em->remove($detail);
        }
    }

    // flushing too early ?
    // $em->flush();
    $this->enableBlameableEventListeners($em);

    foreach($newDetails as $detail)
        if(!$detail->getId()) $em->persist($detail);

    // flushing too early ?
    // $em->flush();

    foreach($newDetails as $detail) {
        $resource = $detail->getResource();

        if(!$library->getResources()->contains($resource))
            $library->addResource($resource);
    }
    // flushing too early ?
    // $em->flush();
    if($this->getUser() === $entity->getUser()) {
        $this->putMembershipContactSetting($entity, $settings);
        $locale = $entity->getLocale();

        if($locale && $entity->getUser()->getLocale() !== $locale)
            $this->setUserLocale($entity);

        // flushing too early ?
        $em->flush();
    }

    if (!doNotFlush) {
        $em->flush();
    }
}

然后在你的putMembershipAction()内:

if($entity->getStatus() === Membership::STATUS_ACCEPTED)
    $this->processUserDetails($em, $library, $entity, $oldDetails, $settings, true);

// .... 


// before return, flush it
$em->flush();
// now returns
return $entity;

请注意,这样做会改变processUserDetails的工作方式,您应该重新验证流程。关键是要将每个实体保存在内存中,并且最后只调用一次flush()

© www.soinside.com 2019 - 2024. All rights reserved.