我使用的是Doctrine 2.5.0版,我有两个实体:Group
和Item
。我正在尝试创建一个唯一约束,以便Items
position
中的Group
不能具有相同的/**
* @Entity
* @Table(uniqueConstraints={
* @UniqueConstraint(name="position", columns={"group_id", "position"})
* )
*/
class Item {
...
}
:
active
这很有效。
我在Item实体中添加了Item
字段,因此我没有删除Item
,而是“停用”它。但现在唯一约束不再起作用,因为Group
使用position
引用和options
保留在数据库中。
查看Doctrine docs,我发现我可以将@UniqueConstraint
属性与/**
* @Entity
* @Table(uniqueConstraints={
* @UniqueConstraint(name="position", columns={"group_id", "position"},
* options={"where":"(active = 1)"})}
* )
*/
class Item {
...
}
中的where子句一起使用:
$item->setActive(false);
$this->_em->persist($item);
$this->_em->flush();
foreach ($item->getNextItems() as $nextItem) {
$nextItem->setPosition($nextItem->getPosition() - 1);
$this->_em->persist($nextItem);
}
$this->_em->flush();
但是我得到了和以前一样的错误:
SQLSTATE [23000]:完整性约束违规:1062重复条目 关键'位置'的'1-1'
这是我的删除代码:
options
知道为什么./doctrine orm:schema-tool:update --force
属性不起作用?
更新
我意识到一种奇怪的行为。每次运行命令DROP INDEX position ON Item;
CREATE UNIQUE INDEX position ON Item (group_id, position);
时,它都会重新创建索引:
options
但是一旦我删除org.mortbay.jetty.webapp.WebAppContext.getUnavailableException()
属性并运行命令,我得到:
无需更新 - 您的数据库已与当前数据库同步 实体元数据。
答案 0 :(得分:1)
我似乎从Doctrine docs中读过这篇文章:
要用于部分索引的SQL WHERE条件。它只会对支持的平台产生影响。
research之后:
MySQL不支持这种性质的部分索引
我的解决方案是检查Item
在实体内的LifeCycleEvent中是否真的独一无二:
/**
* @PostPersist @PostUpdate
*/
public function checkUnicity(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
$em = $eventArgs->getEntityManager();
// checking unicity here
// throw exception if not
}
答案 1 :(得分:0)
如果您已在数据库中存储数据,然后在首先添加唯一约束之后,请在数据库中检查您是否具有唯一值。