symfony 2仅在反序列化后才持久化对象

时间:2013-04-04 15:28:47

标签: json symfony merge doctrine-orm jmsserializerbundle

一直在摸我的头。我有一个symfony 2 json api,它为Android应用程序提供数据。

api序列化数据并使用JMSSerializerBundle将其发送到应用程序,完全没有问题。然后我使用GSON反序列化为本机java对象。

然后我的应用会进行更改并将数据发回API。

我的问题是,当我反序列化从应用程序发送的json并尝试持久化/合并时,在数据库中为已经存在的实体创建新对象。 symfony 2可以确定一个对象是否是新的?我原以为如果它有记录的Id,它会知道它是要更新而不是创建。

这是我的控制器代码:

public function postSuggestionAction()
{

    $content = $this->get("request")->getContent();

    if (!empty($content))
    {
        $serializer = $this->get('jms_serializer');
        $suggestion = $serializer->deserialize($content, 'Calling\WebBundle\Entity\Suggestion', 'json');

        $em = $this->getDoctrine()->getManager();
        $em->persist($suggestion);
        $em->merge($suggestion->getCategory());
        $em->merge($suggestion->getNumber());
        $em->merge($suggestion->getCaller());
        $em->flush();

        $view = $this->view(true, 200);
        return $this->handleView($view);

    }

    $view = $this->view(false, 404);
    return $this->handleView($view);



}

提前致谢 史蒂夫

1 个答案:

答案 0 :(得分:1)

<强>更新

它确实可以使用EntityManager :: merge()方法。但是,您需要在实体的映射上使用cascade = MERGE或cascade = ALL选项。您的代码应该成为:

public function postSuggestionAction()
{

    $content = $this->get("request")->getContent();

    if (!empty($content))
    {
        $serializer = $this->get('jms_serializer');
        $detachedSggestion = $serializer->deserialize($content, 'Calling\WebBundle\Entity\Suggestion', 'json');

        $em = $this->getDoctrine()->getManager();
        $suggestion = $em->merge($detachedSuggestion);
        $em->flush();

        $view = $this->view(true, 200);
        return $this->handleView($view);

    }

    $view = $this->view(false, 404);
    return $this->handleView($view);



}

原始答案 不,除了基于区别(唯一)列查询Doctrine实体之外,没有办法做到这一点。最好的方法是从JSON获取ID,但如果不这样做,则需要有一种方法来比较您的实体,看它们是否相等。然后,您可以从数据库中查询它。

你的逻辑就是:

  • 在数据库中搜索对象(SELECT s FROM Suggestion WHERE s.id = :id;如果您有ID)
  • 返回对象或null;如果为null,请保留您的逻辑,否则将JSON中的更改反映到您的对象,然后保持&amp;保存。