Microsoft SQL Server上的自引用ManyToMany关系“可能会导致循环”

时间:2018-06-26 07:31:51

标签: sql-server doctrine-orm doctrine

我有一个实体,负责管理对该类其他实例的引用列表:

/**
 * @ORM\Entity
 */
class TestEntity
{

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="TestEntity")
     */
    public $brothers;


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

SQL语句为:

CREATE TABLE test_entity (id INT IDENTITY NOT NULL, PRIMARY KEY (id));
     CREATE TABLE test_entity_test_entity (test_entity_source INT NOT NULL, test_entity_target INT NOT NULL, PRIMARY KEY (test_entity_source, test_entity_target));
ALTER TABLE test_entity_test_entity ADD CONSTRAINT FK_CE008F84BDB277B2 FOREIGN KEY (test_entity_source) REFERENCES test_entity (id) ON DELETE CASCADE;
ALTER TABLE test_entity_test_entity ADD CONSTRAINT FK_CE008F84A457273D FOREIGN KEY (test_entity_target) REFERENCES test_entity (id) ON DELETE CASCADE;

因此,默认情况下,外键约束为ON DELETE CASCADE

此模型在PostgreSQL(pdo_pgsql)和MySQL(pdo_mysql)上有效,但是在MSSQL(pdo_sqlsrv和sqlsrv)上,我收到以下错误消息:

    An exception occurred while executing 'ALTER TABLE test_entity_test_entity ADD CONSTRAINT FK_CE008F84A457273D FOREIGN KEY (test_entity_target) REFERENCES test_entity (id) ON DELETE CASCADE':                                           

  SQLSTATE [42000, 1785]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Introducing FOREIGN KEY constraint 'FK_CE008F84A457273D' on table 'test_entity_test_entity' may cause cycles or multiple cascade paths. Specify ON DELETE  
   NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

请注意,该错误在执行第二个外键命令时发生(已安装源上的外键,尝试安装目标功能键时会产生该错误)!

我认为

ON DELETE CASCADE是正确的,因为如果删除了TestEntity,也不应再将它作为兄弟存储在任何其他TestEntity中。另外,如果删除了TestEntity,则应删除所有他的兄弟条目。

我很困惑,因为这是标准情况,Microsoft SQL Server应该能够代表它,还是我丢失了什么?

In this SO-post,引用了一篇文章如何“手动”规避我的问题。但我想坚持学说...

编辑:

在向我的TestEntity添加以下(默认)注释之后,我现在很困惑:

/**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="TestEntity")
 * @ORM\JoinTable(name="test_entity_test_entity",
 *      joinColumns={@ORM\JoinColumn(name="test_entity_source", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="test_entity_target", referencedColumnName="id")}
 *      )
 */
public $brothers;

该错误消息消失,并且使用我的TestEntity时联接表中也没有僵尸行保留。

就SQL语句而言,不同之处在于现在缺少ON DELETE CASCADE。因此,ORM似乎在进行级联删除...?

I created a GIST for you很好用,除了实体引用自身的情况外,刷新时我得到notice: undefined index

注意,该测试用例确实可以正常运行,没有使用驱动程序pdo_mysql,pdo_pgsql和 pdo_sqlsrv 的例外。如果我使用 sqlsrv ,则在刷新remove- $ C-unit-of-work时会失败。我不知道为什么。

无论如何,问题是:在生产环境中可以可靠地将理论与MSSQL一起使用吗?

0 个答案:

没有答案