Отношение сущности доктрины не обновляется

0

Я пытаюсь обновить объект отношения "один-два-один" объекта.

Это код, который я использую:

$em    = $this->getDoctrine()->getManager();
$request = Request::createFromGlobals();
$user    = $this->get('security.context')->getToken()->getUser();

# find thread
$thread = $em->getRepository('MyBundle:Thread')->findThreadById($threadid);

# find thread posts
$query = $em->getRepository('MyBundle:Post')->findThreadPosts($thread->getId());

# create form
$form = $this->createForm(new PostType(), new Post($user, $thread));

# handle form
$form->handleRequest($request);
if ($form->isValid()) {

    $post = $form->getData();
    $em->persist($post);
    $em->flush();
    $logger->debug("POST CREATED with id: " . $post->getId());

    $thread->setLastPost($post);
    $thread->addPostCount(1);
    $thread->setLastPostCreator($user);
    $em->flush();


    $logger->debug("ADDED LAST POST TO thread with id: " . $thread->getId());

    $forum = $thread->getForum();
    $forum->setLastPostCreator($user);
    $forum->addPostCount(1);
    $forum->setLastPostCreator($user);
    $forum->setLastPost($post);
    $em->flush();

    $this->get('session')->getFlashBag()->add(
        'notice',
        'Your post has been added!'
    );
}

$data['posts']  = $posts;
$data['thread'] = $thread;
$data['form']   = $form->createView();

Отображение сообщения:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="MyBundle\Entity\Post" table="post">

    <id name="id" type="integer" column="id">
      <generator strategy="IDENTITY"/>
    </id>
    <field name="text" type="text" column="text" nullable="false"/>

    <many-to-one field="thread" target-entity="Thread" inversed-by="posts">
      <join-columns>
          <join-column name="thread_id" referenced-column-name="id"/>
      </join-columns>
    </many-to-one>

  </entity>
</doctrine-mapping>

Отображение темы:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="MyBundle\Entity\Thread" table="thread">
    <id name="id" type="integer" column="id">
      <generator strategy="IDENTITY"/>
    </id>

    <field name="postCount" type="integer" column="post_count" nullable="false"/>

    <one-to-one field="lastPost" target-entity="Post">
       <join-column name="last_post_id" referenced-column-name="id"/>
    </one-to-one>

    <one-to-many field="posts" target-entity="Post" mapped-by="thread" />

  </entity>
</doctrine-mapping>

Объект: установщик потоков

public function setLastPost(Post $lastPost)
{
    $this->lastPost = $lastPost;
}

public function getLastPost()
{
    return $this->lastPost;
}

Поэтому всякий раз, когда я добавляю сообщение, я обновляю его родительский (поток). Таким образом, поток имеет последнее сообщение в виде ссылки "много-в-один". Я также обновляю счет только как вопрос кэширования и сокращения объединений.

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

любые идеи/мысли по этому поводу? моя лучшая догадка заключалась в том, что он не обнаружил изменений, но я понятия не имею, как сделать недействительными такие данные.

Теги:
doctrine2

3 ответа

2
Лучший ответ

Я думаю, проблема в том, что вы настраиваете и сохраняете "обратную сторону" отношений. Документы говорят:

Доктрина будет проверять только принадлежность ассоциации к изменениям.

а также

ManyToOne всегда является владением двунаправленной ассоциацией.

Таким образом, в вашем случае у вас есть многоточечное двунаправленное отношение между потоком и lastPosts, где объект lastPost является "стороной-обладателем" (многосторонняя сторона), а поток - "обратная сторона". Я считаю, что у вас должна быть функция setThread() для вашего объекта Post, и если после обработки формы вы запускаете $post-> setThread ($ thread), а затем сохраняете ($ post), все будет работать.

Кроме того, IMO, похоже, что вы должны иметь отношения между thread-> сообщениями и использовать пользовательскую функцию репозитория, или находить и сортировать по дате createdAt (при условии, что она существует) для получения "последнего сообщения". Мне кажется, что отношения "Много нитей к одному последнему сообщению" мне кажутся неправильными, не должны ли нить иметь только один "последний пост" (aka oneToOne)?

  • 0
    Последний пост - это сложный запрос, который также часто обновляется на оживленном форуме. Вот почему я решил иметь поле кэширования (которое обычно никогда не используется в СУБД). Пожалуйста, исправьте меня, если я ошибаюсь. Сейчас я проверяю ваше решение.
  • 0
    Да, это правильно, это должно быть один на один. сейчас корректирую и обновлю если работаю как можно скорее
Показать ещё 9 комментариев
0

Я просто столкнулся с этим. Решение, которое сработало для меня, состояло в вызове $em->merge($entity); на каждом из объектов на стороне "много", а затем $em->flush(); ,

0

ваш метод $thread-> setLastPost ($ post) выглядит следующим образом:

public function setLastPost(Post $post)
{
    $this->lastPost = $post;
}

Вызывается? Что происходит при вставке отладочной инструкции?

Правильно ли вы установили право на право, если это необходимо?

"So, all that by_reference=false really does is force the framework to call the setter on the parent object."

http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference

Если вышеприведенные рекомендации не работают, не могли бы вы предоставить дополнительную информацию, такую как FormTypes и соответствующие сущностные сеттеры и геттеры?!

  • 0
    Здравствуйте, спасибо за ваш ответ. Функция setLastPost вызывается и выглядит как сеттер, который вы опубликовали. by_reference не требуется, так как я получаю поток. Я обновил свой оригинальный пост более подробным кодом. Я не думаю, что FormTypes актуальны в этом случае. я также добавил свои сущности
  • 0
    Что происходит, когда вы делаете это: public function setLastPost (Post $ post) {$ this-> lastPost = $ post; $ Post-> setThread ($ это); }
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню