Doctor模块:实体关系被水化,但不坚持实体

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

我在用户(拥有方)和用户组之间存在多对多关系,并且在使用教义模块的水化器创建新用户组时遇到问题。

当我创建一个新的用户组并进行水合,持久化和刷新时,记录在数据库中会更改,但是代表用户组的实体变量本身在水合后并不会以任何用户结尾。

上下文:我们有一个REST控制器路由,可用于通过POST创建新的用户组。它接受参数以通过水合作用对某些用户进行初始化。此操作成功更新了数据库,但是其响应不正确。应该从现在持久的实体中提取数据,并将其回显给客户端。但是,它无法提取任何用户,因此响应错误地返回为空组。不使用水化器的提取方法,而是使用更多基本的指令也将失败-似乎实体变量本身在持久化之后并没有保持最新状态。

所以我的问题确实是:为什么水化器不提取用户?如果我们弄乱了所有者/反向关联,为什么它仍然起作用(即,将用户持久保存到数据库中而不将其持久化到数据库中)实体)。

这里是相关代码,可能只需要前两个块。

public function create($data) {
    ...

    $hydrator = $this->getHydrator();
    $em = $this->getEntityManager();
    $entity = $this->getEntity();
    $entity = $hydrator->hydrate($data, $entity);

    // Persist the newly created entity
    $em->persist($entity);

    // Flush the changes to the database
    $em->flush();

    return $this->createResponse(
        201,
        true,
        'Created item',
        $this->getHydrator()->extract($entity)
    );

以下是水化工正在使用的二传手和吸气剂:

... more fields... 

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="groups")
 */
protected $users;

...

/**
 * Getter for users
 *
 * @return mixed
 */
public function getUsers() {
    return $this->users;
}

public function addUsers(Collection $users) {
    foreach ($users as $user) {
        $user->addGroups(new ArrayCollection(array($this)));
    }
}

我认为以上是唯一相关的代码,但是如果我弄错了,我会再包括一些其他代码。这是getHydrator方法:

  public function getHydrator() {
      if(null === $this->hydrator) {
          $hydrator = new DoctrineObject($this->getEntityManager(), $this->getEntityName());
          // Use Entity metadata to add extraction stategies for associated fields
          $metadata = $this->em->getClassMetadata($this->getEntityName());

          foreach ($metadata->associationMappings as $field => $mapping) {
              // Use our custom extraction strategies for single and collection valued associations
              if($metadata->isSingleValuedAssociation($field)) {
                  $hydrator->addStrategy($field, new RestfulExtractionStrategy());
              }
              else if($metadata->isCollectionValuedAssociation($field)) {
                  $hydrator->addStrategy($field, new RestfulExtractionCollectionStrategy());
              }
          }
          $this->hydrator = $hydrator;
      }

      return $this->hydrator;
  }

这里是RestfulExtractionCollectionStrategy(此处未使用其他策略,我已经对此进行了验证。)>

namespace Puma\Controller;
use DoctrineModule\Stdlib\Hydrator\Strategy\AllowRemoveByValue;
use Doctrine\Common\Collections\Collection;

/**
 * You can use this strategy with fields that are collections,
 * e.g. one to many.  You need to use the RestfulExtractionStrategy
 * if you want to get extract entities from a singleton field, e.g. manyToOne.
 **/
class RestfulExtractionCollectionStrategy extends AllowRemoveByValue
{
    public function extract($value)
    {
        if ($value instanceof Collection) {
            $return = array();
            foreach ($value as $entity) {
                if(method_exists($entity, 'getId')){
                    $return[] = $entity->getId();
                }
                else {
                    $return[] = $entity;
                }
            }
            return $return;
        }
        return $value;
    }
}

我在用户(拥有方)和用户组之间存在多对多关系,并且在使用教义模块的水化器创建新用户组时遇到问题。当我创建一个新的用户组时...

php doctrine-orm doctrine
2个回答
0
投票

[我想我终于解决了-我在“ setter”方法中添加了一行addUsers,该方法在更新相关用户之后手动更新了组的users属性。不过,如果这是最佳做法,我会感到有些惊讶。我以为更新拥有方(用户)会自动更新相反方(用户组)。也许我错了。 [如果其他人有更好的主意,我会很乐意将答案归功于他们。


0
投票

我对水合作用等不太熟悉,所以您的代码对我来说有点奇怪,我不能保证这会起作用,但是您是否尝试在刷新后刷新实体(即$em->refresh($entity))并可能返回实体而不是$this->getHydrator()->extract($entity)

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