Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony2&;SonataAdmin:ManyToMany字段在创建时被插入两次(导致主键重复错误),但在更新时有效_Php_Symfony_Doctrine Orm_Symfony Sonata_Sonata Admin - Fatal编程技术网

Php Symfony2&;SonataAdmin:ManyToMany字段在创建时被插入两次(导致主键重复错误),但在更新时有效

Php Symfony2&;SonataAdmin:ManyToMany字段在创建时被插入两次(导致主键重复错误),但在更新时有效,php,symfony,doctrine-orm,symfony-sonata,sonata-admin,Php,Symfony,Doctrine Orm,Symfony Sonata,Sonata Admin,我正在尝试向故事实体添加标记。我已经创建了自己的捆绑包、表单类型和数据转换器来加以利用,我认为一切都很好……但事实证明,只有在向现有故事添加标记时才会出现这种情况。如果我在创建故事的同时尝试添加标记,我会抛出一个异常,因为它尝试在连接表中创建记录两次,从而导致重复的主键错误 我不认为问题出在我的自定义表单类型和数据转换器上,因为我在将请求绑定到表单之后,但在持久化之前,已经在控制器中进行了调试,这里的一切看起来都非常好-我的故事实体只包含我添加的标记,没有重复项 以下是tags属性的配置,以防有

我正在尝试向故事实体添加标记。我已经创建了自己的捆绑包、表单类型和数据转换器来加以利用,我认为一切都很好……但事实证明,只有在向现有故事添加标记时才会出现这种情况。如果我在创建故事的同时尝试添加标记,我会抛出一个异常,因为它尝试在连接表中创建记录两次,从而导致重复的主键错误

我不认为问题出在我的自定义表单类型和数据转换器上,因为我在将请求绑定到表单之后,但在持久化之前,已经在控制器中进行了调试,这里的一切看起来都非常好-我的故事实体只包含我添加的标记,没有重复项

以下是tags属性的配置,以防有帮助:

/**
 * @ORM\ManyToMany(targetEntity="Tag")
 * @ORM\JoinTable(name="story__story_tags",
 *   joinColumns={@ORM\JoinColumn(name="story_id", referencedColumnName="id")},
 *   inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
 * )
 */
protected $tags;
以下是我的日志输出的摘录:

INSERT INTO stories (created_at, updated_at, published_at, author_id, media_id, title, short_title, summary, text, slug, active, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ({"1":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},"2":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},"3":{"date":"2012-09-11 14:56:00","timezone_type":3,"timezone":"Europe\/London"},"4":10,"5":68,"6":"Story with tags","7":"","8":"Test","9":"<p>test<\/p>","10":"story-with-tags","11":true,"12":"media"})
INSERT INTO story__media (id, story_media_id, media_size, show_caption) VALUES (?, ?, ?, ?) ({"1":"130","2":null,"3":"0","4":false})
SELECT s0_.slug AS slug0 FROM stories s0_ LEFT JOIN story__gallery s1_ ON s0_.id = s1_.id LEFT JOIN story__media s2_ ON s0_.id = s2_.id LEFT JOIN story__competition s3_ ON s0_.id = s3_.id WHERE s0_.slug LIKE 'story-with-tags-872875%' AND s0_.id <> ? ([130])
INSERT INTO story__counters (story_id, hits, shares, comments, updated_at) VALUES (?, ?, ?, ?, ?) ({"1":130,"2":0,"3":0,"4":0,"5":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"}})
INSERT INTO story__sections (story_id, section_id, section_position) VALUES (?, ?, ?) ({"1":130,"2":212,"3":1})
UPDATE stories SET slug = ?, updated_at = ? WHERE id = ? (["story-with-tags-872875",{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},130])
website/story/130 (DELETE) 11.00 ms
website/story/130 (PUT) 5.12 ms
Context: { title: 'Story with tags', summary: Test, text: '<p>test</p>', author: billy-wiggins, publishedAt: 1347371760, tags: [test] }
INSERT INTO story__story_tags (story_id, tag_id) VALUES (?, ?) ([130,9])
INSERT INTO story__story_tags (story_id, tag_id) VALUES (?, ?) ([130,9])
插入故事(创建于、更新于、发布于、作者id、媒体id、标题、短标题、摘要、文本、slug、活动、类型)值(、、、、、、、、、、、、、)({“1”:{“日期”:“2012-09-11 15:07:20”、“时区类型”:3,“时区”:“欧洲\伦敦”},“2”:{“日期”:“2012-09-11 15:07:20”、“时区类型”:3,“时区”:“欧洲\伦敦”},“3:{”date:“2012-09-11 14:56:00”,“timezone_type”:3,“timezone:“Europe\/London”},“4”:10,“5”:68,“6:“带标签的故事”,“7:“,”8:“Test”,“9:“Test”,“10:“带标签的故事”,“11”:true,“12:“media”})
在故事媒体(id、故事媒体id、媒体大小、显示标题)中插入值(?,?,?)({“1”:“130”,“2”:null,“3”:“0”,“4”:false})
从s0上的故事s0_uuu左加入故事_uu画廊s1_uu.id=s1_uu.id左加入故事_uu媒体s2_uuS0上的故事s0_u.id=s2_uu.id左加入故事_uu比赛s3_u.id=s3_u.id,其中s0_u.slug类似于“带标签的故事-872875%”和s0_u.id([130])
在故事计数器(故事id、点击、共享、评论、更新时间)中插入值(?、、?、?、?)({“1”:130,“2”:0,“3”:0,“4”:0,“5”:{“日期”:“2012-09-11 15:07:20”,“时区类型”:3,“时区”:“欧洲\伦敦”})
将值(?,?)插入到故事部分(故事id、章节id、章节位置)({“1”:130,“2”:212,“3”:1})
更新故事集slug=?,更新的_at=?其中id=?([“story-with-tags-872875”,{“date”:“2012-09-11 15:07:20”,“timezone_type”:3,“timezone”:“Europe\/London”},130])
网站/story/130(删除)11.00 ms
网站/story/130(PUT)5.12 ms
上下文:{title:'Story with tags',摘要:Test,文本:'Test

',作者:billy wiggins,publishedAt:1347371760,tags:[Test]} 插入故事故事标签(故事id,标签id)值(?,)([130,9]) 插入故事故事标签(故事id,标签id)值(?,)([130,9])
从第三行到最后一行,您可以看到,我的实体已被编入elasticsearch,它只包含一个标记:“test”。接下来,您可以看到两个重复的查询试图将标记9与故事130联系起来。有人知道为什么会发生这种情况吗

是否可能以某种方式使这些insert查询使用
insert IGNORE
语法,因为这样至少可以绕过问题


谢谢!

好吧,我已经设法找到了一种方法,用一个臭烘烘的黑客来“修复”这个问题。除非没有其他方法,否则我不太可能接受这是正确的答案,所以如果你知道一种很好的修复方法,请回复

因为问题只会在同时创建我的故事实体和标记时出现,所以我扩展了基本管理类的
create
方法,如下所示:(准备好忍住鼻子…..现在!)


肯定有更整洁的解决方案吗?

我已经设法找到了一种方法,用一个臭烘烘的黑客来“修复”这个问题。除非没有其他方法,否则我不太可能接受这是正确的答案,所以如果你知道修复这个问题的好方法,请一定回复

因为问题只会在同时创建我的故事实体和标记时出现,所以我扩展了基本管理类的
create
方法,如下所示:(准备好忍住鼻子…..现在!)

肯定有更整洁的解决方案吗?

这是一个结构()

对于所有的一对多和多对多关系,都必须这样做。

把这称为_构造():


您必须对所有的一对多和多对多关系执行此操作。

此解决方案效果良好:

public function __construct()
{
    $this->tags = new ArrayCollection();
}

public function addTag(Tag $tag)
{
    if (!this->tags->contains($tag)) {
        $this->tags->add($tag);
    }
}

下次不添加重复密钥

此解决方案工作正常:

public function __construct()
{
    $this->tags = new ArrayCollection();
}

public function addTag(Tag $tag)
{
    if (!this->tags->contains($tag)) {
        $this->tags->add($tag);
    }
}

下次不会添加重复键

谢谢,这是一个有效点,但我已经在我的故事实体的构造函数中得到了它,所以这不是问题的原因。parent::create($object)在做什么?它会持久化给定的对象,但会调用pre和post persist方法(特定于Admin类-不要与Doctrine lifecycle events混淆)并设置对象安全性(如果需要)。我本可以保留对象并手动刷新实体管理器,但我认为这种方式更干净。请注意,我没有调用
parent::update($object)
之后,因为我不希望更新事件也被触发。我认为您在代码中有一些问题。最简单的方法是不要调用parent::create(),而是手动尝试持久化$object;至少您会知道问题在哪里。$em->persist($object);$em->flush()谢谢,这是一个有效的观点,但我已经在我的故事实体的构造函数中得到了这一点,所以这不是问题的原因。parent::create($object)在做什么?它持久化给定的对象,但调用pre和post persist方法(特定于Admin类-不要与生命周期事件混淆)并设置对象安全性(如果需要)。我本可以保留对象并手动刷新实体管理器,但我认为这种方式更干净。请注意,我没有在事后调用
parent::update($object)
,因为我不希望更新事件不发生
public function __construct()
{
    $this->tags = new ArrayCollection();
}

public function addTag(Tag $tag)
{
    if (!this->tags->contains($tag)) {
        $this->tags->add($tag);
    }
}