symfony2 JMSSerializerBundle 反序列化实体与 OneToMany 关联



我在 doctrine2 设置中Category OneToMany Post

关联如下:

类别:

...
/**
 * @ORMOneToMany(targetEntity="Post", mappedBy="category")
 * @Type("ArrayCollection<PlatformBlogBundleEntityPost>")
 */
protected $posts;
...

发布:

...
/**
 * @ORMManyToOne(targetEntity="Category", inversedBy="posts")
 * @ORMJoinColumn(name="category_id", referencedColumnName="id")
 * @Type("PlatformBlogBundleEntityCategory")
 */
protected $category;
...

我正在尝试反序列化以下json对象(数据库中已经存在id为1的两个实体)

{
    "id":1,
    "title":"Category 1",
    "posts":[
        {
            "id":1
        }
    ]
}

使用 JMSSerializerBundle 序列化程序的反序列化方法配置了 doctrine 对象构造函数

jms_serializer.object_constructor:
    alias: jms_serializer.doctrine_object_constructor
    public: false

结果如下:

PlatformBlogBundleEntityCategory {#2309
  #id: 1
  #title: "Category 1"
  #posts: DoctrineCommonCollectionsArrayCollection {#2314
    -elements: array:1 [
      0 => PlatformBlogBundleEntityPost {#2524
        #id: 1
        #title: "Post 1"
        #content: "post 1 content"
        #category: null
      }
    ]
  }
}

乍一看还好。问题是,关联的Post category字段设置为 null ,导致persist()上没有关联。如果我尝试反序列化它:

{
    "id":1,
    "title":"Category 1",
    "posts":[
        {
            "id":1
            "category": {
                "id":1
            }
        }
    ]
}

它工作正常,但这不是我想做的:(我怀疑解决方案可能是以某种方式颠倒实体的保存顺序。如果帖子首先保存,类别第二,这应该有效。

如何正确保存此关联?

不知道这是否仍然与您相关,但解决方案非常简单。

您应该为关联配置带有资源库的访问器,例如:

/**
 * @ORMOneToMany(targetEntity="Post", mappedBy="category")
 * @Type("ArrayCollection<PlatformBlogBundleEntityPost>")
 * @Accessor(setter="setPosts")
 */
protected $posts;

序列化程序将调用 setter 方法来从 json 填充posts。其余的逻辑应该在setPosts内处理:

public function setPosts($posts = null)
{
    $posts = is_array($posts) ? new ArrayCollection($posts) : $posts;
    // a post is the owning side of an association so you should ensure
    // that its category will be nullified if it's not longer in a collection
    foreach ($this->posts as $post) {
        if (is_null($posts) || !$posts->contains($post) {
            $post->setCategory(null);
        }
    }
    // This is what you need to fix null inside the post.category association
    if (!is_null($posts)) {
        foreach ($posts as $post) {
            $post->setCategory($this);
        }
    }
    $this->posts = $posts;
}

最新更新