sha*_*ran 3 php mysql doctrine symfony doctrine-orm
我想与Symfony和Doctrine建立一个简单的多对多关系.这实际上是一个单向一对多关联,可以通过连接表进行映射,因为文档指示我正在使用YAML文件进行配置,使用以下代码:
在文件Content.orm.yml中:
manyToMany:
comments:
cascade: ["persist","remove"]
onDelete: CASCADE
options:
cascade:
remove: true
persist: true
#refresh: true
#merge: true
#detach: true
orphanRemoval: false
orderBy: null
targetEntity: Comment
joinTable:
name: content_comments
joinColumns:
content_id:
referencedColumnName: id
inverseJoinColumns:
comment_id:
referencedColumnName: id
unique: true
Run Code Online (Sandbox Code Playgroud)
这会产生以下SQL命令:
$ php app/console doctrine:schema:update --dump-sql | grep -i "comment\|content"
CREATE TABLE comment (id INT AUTO_INCREMENT NOT NULL, text LONGTEXT NOT NULL, content_id INT NOT NULL, creation_date DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE contents (id INT AUTO_INCREMENT NOT NULL, user INT DEFAULT NULL, user_id INT NOT NULL,file VARCHAR(255) DEFAULT NULL, INDEX IDX_B4FA11778D93D649 (user), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE content_comments (content_id INT NOT NULL, comment_id INT NOT NULL, INDEX IDX_D297CC584A0A3ED (content_id), UNIQUE INDEX UNIQ_D297CC5F8697D13 (comment_id), PRIMARY KEY(content_id, comment_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE contents ADD CONSTRAINT FK_B4FA11778D93D649 FOREIGN KEY (user) REFERENCES users (id);
ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC584A0A3ED FOREIGN KEY (content_id) REFERENCES contents (id);
ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC5F8697D13 FOREIGN KEY (comment_id) REFERENCES comment (id);
Run Code Online (Sandbox Code Playgroud)
但正如您所看到的,FOREIGN KEY指令没有"ON DELETE CASCADE",即使我尝试放置我找到的所有YAML注释.
因为在代码中,我试图删除"内容"实体和与此代码关联的所有"注释":
$comments = $content->getComments();
// Remove first the parent
$entity_manager->remove($content);
$entity_manager->flush();
// Remove the childs
foreach($comments as $comment)
{
$entity_manager->remove($comment);
}
$entity_manager->flush();
Run Code Online (Sandbox Code Playgroud)
这会产生以下异常.
An exception occurred while executing 'DELETE FROM comment WHERE id = ?' with params [1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`bb2server`.`content_comments`, CONSTRAINT `FK_D297CC5F8697D13` FOREIGN KEY (`comment_id`) REFERENCES `comment` (`id`))
Run Code Online (Sandbox Code Playgroud)
那么,我做错了什么?或者如何强迫Doctrine在多对多关系中加入"ON DELETE CASCADE"?
我唯一肮脏的解决方法是删除SQL查询并重建自己,但我需要Doctrine在架构中创建查询:更新以避免我的修补:
mysql> show create table content_comments;
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| content_comments | CREATE TABLE `content_comments` (
`content_id` int(11) NOT NULL,
`comment_id` int(11) NOT NULL,
PRIMARY KEY (`content_id`,`comment_id`),
UNIQUE KEY `UNIQ_D297CC5F8697D13` (`comment_id`),
KEY `IDX_D297CC584A0A3ED` (`content_id`),
CONSTRAINT `FK_D297CC584A0A3ED` FOREIGN KEY (`content_id`) REFERENCES `contents` (`id`),
CONSTRAINT `FK_D297CC5F8697D13` FOREIGN KEY (`comment_id`) REFERENCES `comment` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> ALTER TABLE content_comments DROP FOREIGN KEY FK_D297CC5F8697D13;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE content_comments ADD CONSTRAINT FK_D297CC5F8697D13 FOREIGN KEY (`content_id`) REFERENCES `contents` (`id`) ON DELETE CASCADE;
Query OK, 10 rows affected (0.07 sec)
Records: 10 Duplicates: 0 Warnings: 0
Run Code Online (Sandbox Code Playgroud)
编辑:解决方法.我需要将onDelete:CASCADE放在JoinColumns下
manyToMany:
comments:
cascade: ["persist","remove"]
onDelete: CASCADE
options:
cascade:
remove: true
persist: true
#refresh: true
#merge: true
#detach: true
orphanRemoval: false
orderBy: null
targetEntity: Comment
joinTable:
name: content_comments
joinColumns:
content_id:
referencedColumnName: id
onDelete: CASCADE
inverseJoinColumns:
comment_id:
referencedColumnName: id
unique: true
onDelete: CASCADE
Run Code Online (Sandbox Code Playgroud)
小智 7
您必须在“joinColumns”和“inverseJoinColumns”中添加“JoinColumn”定义,如下所示:
/**
* @var Collection|null
* @ManyToMany(targetEntity="...")
* @JoinTable(name="...",
* joinColumns={@JoinColumn(name="`...`", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={@JoinColumn(name="`...`", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
Run Code Online (Sandbox Code Playgroud)
您可以在那里添加 onDelete 级联(数据库级别)定义
我从来没有使用YAML格式来定义我的实体和关系,所以我不知道它是否相同,但是注释onDelete选项属于@ORM\JoinColumn注释:
/**
* @var \AppBundle\Entity\Actor $actor
*
* @ORM\ManyToOne(targetEntity="Actor", inversedBy="fields")
* @ORM\JoinColumn(name="actor_id", referencedColumnName="id", nullable=false, onDelete="cascade")
*/
protected $actor = null;
Run Code Online (Sandbox Code Playgroud)
PS:快速搜索后我找到了你的答案:https://stackoverflow.com/a/8330495/5192753
| 归档时间: |
|
| 查看次数: |
10664 次 |
| 最近记录: |