【问题标题】:Unique Constraints in Doctrine 2, Symfony 2Doctrine 2,Symfony 2 中的独特约束
【发布时间】:2012-01-22 15:39:29
【问题描述】:

我想在我的 Doctrine 2 实体中创建一个唯一约束,以便 nametest 在列方面是唯一的。意义

  • obj1

    • 姓名:姓名1
    • 测试:测试
  • obj2

    • 姓名:姓名2
    • 测试:测试

这应该会在测试重复时触发错误。

我尝试使用唯一约束 (Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity)。试过了

 * @UniqueEntity("name")
 * @UniqueEntity("test")

 * @UniqueEntity({"name", "test"})

似乎只有在我的名称和测试都重复时才会触发错误。例如。

  • obj1

    • 姓名:姓名1
    • 测试:测试
  • obj2

    • 姓名:姓名2
    • 测试:测试

什么是正确的设置?或者我可能在某个地方犯了错误?

也许我应该包括如下教义注释:

@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})

但我认为这仍然无法处理我的 symfony 表单验证?

更新

我的测试代码:

/**
 * @ORM\Entity
 * @ORM\Table(name="roles") 
 * @UniqueEntity("name")
 * @UniqueEntity("test")
 */
class Role {

    /**
     * @var integer
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @var string
     * 
     * @ORM\Column(type="string", length=32, unique=true)
     * @Assert\MaxLength(32)
     * @Assert\Regex("/^[a-zA-Z0-9_]+$/")
     */
    protected $name;

}

$v = $this->get('validator');

$role = new Role();
$role->setName('jm');
$role->setTest('test');
$e = $v->validate($role);
echo '=== 1 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role);            

$role2 = new Role();
$role2->setName('john');
$role2->setTest('test');
$e = $v->validate($role2);
echo '=== 2 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role2);

$em->flush();

第一次运行时(空表):

=== 1 ===object(Symfony\Component\Validator\ConstraintViolationList)#322 (1) {
  ["violations":protected]=>
  array(0) {
  }
}
=== 2 ===object(Symfony\Component\Validator\ConstraintViolationList)#289 (1) {
  ["violations":protected]=>
  array(0) {
  }
}

但我确实在数据库层收到关于唯一约束的错误。那么我应该如何让验证层工作呢?

【问题讨论】:

  • 在您的第二个示例中,没有一个字段是重复的。这让你的问题有点不清楚。
  • @gre0ire, test 重复?
  • 糟糕,抱歉。但在此之前,您会说“两者”。那么第二个例子有什么问题呢?
  • 你可能应该在你的例子后面加上“不会触发任何错误”之类的东西。
  • @greg0ire,在第二个例子中,test 是重复的。我预计会出现验证错误。

标签: validation symfony doctrine-orm


【解决方案1】:

在Table注解中,还可以设置多个columns的索引。

/** * @ORM\实体 * @ORM\Table(name="ecommerce_products",uniqueConstraints={ * @ORM\UniqueConstraint(name="search_idx", columns={"name", "email"})}) */

或使用 YAML 格式:

Namespace\Entity\EntityName:
    type: entity
    table: ecommerce_products
    uniqueConstraints:
        uniqueConstraint:
            columns: [name, email]

【讨论】:

  • 当该字段与另一个表有关系时?喜欢private $author。您不能将 author 或 author_id 放入唯一的。我该如何解决?
  • @hugomn 如果它被连接到另一个实体,您可以添加:“myEntity_id”。向@-yvoyer 提问:如何添加服装信息? (或如何获得错误页面?)
  • @hugomn,我认为基于连接列定义约束仍然有效。前任。鉴于您定义了@JoinColumn(name="customer_id", referencedColumnName="id") 的属性,在约束中指定customer_id 应该可以工作......我的猜测是唯一约束使用的是mysql而不是php的定义。我的意思是唯一约束应该有mysql列的名称customer_id,而不是PHP属性$customer
  • @Timmz,不确定我是否理解您关于错误页面和自定义消息的问题?它似乎与当前问题无关。
  • 如果您想检查相关实体,仍然输入 php 的名称,否则会出现错误:The field "country_id" is not mapped by Doctrine, so it cannot be validated for uniqueness.。使用这个:* @UniqueEntity({"country_id", "product_id"}) 和字段:* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", inversedBy="products") * @ORM\JoinColumn(name="country_id", referencedColumnName="id", nullable=true, onDelete="set null") */ protected $country;
【解决方案2】:

这些分别检查字段:

@UniqueEntity("name")
@UniqueEntity("test")

也就是说,第一个将在有重复的 name 值时触发,而第二个 - 当有重复的 test 值时。

如果您希望在两者 nametest 包含相同的组合 时验证失败,您可以使用:

@UniqueEntity({"name", "test"})

对于您想要的,第一种方法应该有效 - 除非您在其他地方做错了什么。还要尝试清除缓存以确保不是它的错。

更新

我的建议是关于应用端的验证部分。如果您使用 Doctrine 生成数据库模式,则需要为 each 列提供 Doctrine 级别的注释——当然,如果您想让它们彼此独立,那么:

@Column(type = "string", unique = true)
private $name;

@Column(type = "string", unique = true)
private $test;

这些方法相辅相成——不排斥。 @UniqueEntity 确保副本甚至不会到达数据库层,而 @Column 确保如果到达,数据库层不会让它通过。

【讨论】:

  • 奇怪的是UniqueEntity,它不起作用!仅当两个字段重复时才会触发错误,请尽快查看我对主要问题的更新
  • 如果我想使用@UniqueEntity,我应该把它放在我的代码哪里?
  • 1 点赞也解释了@UniqueEntity 和@Column(unique=true)之间的区别 >
猜你喜欢
  • 2013-06-15
  • 1970-01-01
  • 2016-05-14
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
相关资源
最近更新 更多