【问题标题】:Doctrine : UniqueEntity on foreign property?学说:关于外国财产的唯一实体?
【发布时间】:2026-01-13 05:40:01
【问题描述】:

是否可以在外来对象属性上使用 UniqueEntity 注释?

例如我有两个班级:

class A {
    private $id;
    private $num;

    /**
     * @ORM\ManyToOne(targetEntity="B" ....)
     */
    private $b;

    ...
}


class B {
    private $id;
    private $sku;

    ...
}

我需要阻止用户输入已用于 B.sku 的 A.num。 我想做这样的事情:

/**
 * @UniqueEntity(fields={"num","b.sku"})
 */
class A {
    ...
}

【问题讨论】:

  • 我认为不可能(像这样)。如果有的话,我希望您必须将 sku 设为 joinColumn,然后将属性 b 上的关系标记为唯一。即便如此,我认为这不会那么容易,因为如果您在 b 中有多个具有相同 sku 的条目,并且您通过 sku 引用对象,我不确定 Doctrine 是否可以安全地识别用于此引用的哪一行。跨度>
  • 您是想在数据库级别强制执行数据完整性,还是只想通过使用 Symfony 的 validator 组件来检查您的 A 实体是否有效?
  • @AlanT。我只是想在刷新之前检查我的 A Entity 是否有效。

标签: symfony doctrine-orm annotations foreign-keys


【解决方案1】:

对于这种情况,您可以尝试在数据库级别强制执行数据完整性,但此类约束的实现主要取决于您的 RDBMS (an exemple here)。据我所知,Doctrine 只允许添加 uniquecheck 约束,因此您需要信任您的应用程序代码才能正确验证您的实体,然后才能将其保存在这里。

为此,您可以使用CallbackExpression 约束来创建自定义验证规则,而不是UniqueEntity。由于您的规则不是那么复杂,因此使用@Assert\Expression 会更简洁。这样的事情会产生预期的结果:

@Assert\Expression(
    "this.getB() == null or this.getB().getSku() != this.getNum()",
    message="The chosen number should not be the same as the associated number B.sku"
)

正如in the documentation 解释的那样,您可以将此注释直接附加到您的类,也可以将其映射到特定字段。在您的示例中,我想最好将其附加到 num

【讨论】: