【问题标题】:Symfony2 UniqueEntity validation error with entity inheritance实体继承的 Symfony2 UniqueEntity 验证错误
【发布时间】:2012-02-08 15:20:14
【问题描述】:

我有一个合作伙伴、一个买家和一个继承用户类的管理类

当我想添加合作伙伴时,验证器不起作用

 * @DoctrineAssert\UniqueEntity(fields="username", message="Ce nom d'utilisateur est déjà utilisé, veuillez en choisir un autre.", groups={"registration", "account"})
 * @DoctrineAssert\UniqueEntity(fields="mail", message="Cette adresse mail est déjà utilisé, veuillez en choisir un autre.", groups={"registration", "account"})

如果我为已经在数据库中的“合作伙伴”选择用户名,它会显示正确的验证错误。但是,如果我选择数据库中已经存在的“买家”的用户名,则不会进行验证,并且我的数据库中会出现唯一字段错误。

类用户

<?php

namespace Antho\Test\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;

/**
 * Antho\Test\CoreBundle\Entity\User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Antho\Test\CoreBundle\Entity\UserRepository")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"user" = "User", "partner" = "Partner", "buyer" = "Buyer", "admin" = "Admin"})
 * @ORM\HasLifecycleCallbacks()
 * @DoctrineAssert\UniqueEntity(fields="username", message="Ce nom d'utilisateur est déjà utilisé, veuillez en choisir un autre.", groups={"registration", "account"})
 * @DoctrineAssert\UniqueEntity(fields="mail", message="Cette adresse mail est déjà utilisé, veuillez en choisir un autre.", groups={"registration", "account"})
 */
class User implements UserInterface
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $username
     *
     * @ORM\Column(name="username", type="string", length=255, unique=true)
     */
    private $username;

    /**
     * @var string $lastName
     *
     * @ORM\Column(name="last_name", type="string", length=255)
     */
    private $lastName;

    /**
     * @var string $firstName
     *
     * @ORM\Column(name="first_name", type="string", length=255)
     */
    private $firstName;

    /**
     * @var string $mail
     *
     * @ORM\Column(name="mail", type="string", length=255, unique=true)
     */
    private $mail;

    /**
     * @var string $password
     *
     * @ORM\Column(name="password", type="string", length=255)
     */
    private $password;


    public function __construct()
    {
        if ($this->createdAt === null) {
            $this->createdAt = new \DateTime('now');
        }
        $this->isEnabled = true;
    }

    public function __toString()
    {
        return $this->username;
    }

    GETTER and SETTER ...
}

班级合作伙伴

<?php

namespace Antho\Test\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;

/**
 * Antho\Test\CoreBundle\Entity\Partner
 *
 * @ORM\Table(name="partner")
 * @ORM\Entity(repositoryClass="Antho\Test\CoreBundle\Entity\PartnerRepository")
 */
class Partner extends User
{
    /**
     * @ORM\OneToMany(targetEntity="Restaurant", mappedBy="partner", cascade={"remove", "persist"})
     */
    private $restaurants;

    /**
     * @var string $company
     *
     * @ORM\Column(name="company", type="string", length=255)
     */
    private $company;


    public function __construct()
    {
        parent::__construct();
        $this->restaurants = new \Doctrine\Common\Collections\ArrayCollection();
        $this->isValid = false;
    }

    GETTER and SETTER ...
}

类采购员

<?php

namespace Antho\Test\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;

/**
 * Antho\Test\CoreBundle\Entity\Buyer
 *
 * @ORM\Table(name="buyer")
 * @ORM\Entity(repositoryClass="Antho\Test\CoreBundle\Entity\BuyerRepository")
 */
class Buyer extends User
{
    /**
     * @var string $address
     *
     * @ORM\Column(name="address", type="string", length=255)
     */
    private $address;

    /**
     * @var string $city
     *
     * @ORM\Column(name="city", type="string", length=255)
     */
    private $city;

    /**
     * @var string $zip
     *
     * @ORM\Column(name="zip", type="string", length=255)
     */
    private $zip;

    /**
     * @var boolean $newsletter
     *
     * @ORM\Column(name="newsletter", type="boolean")
     */
    private $newsletter;


    public function __construct()
    {
        parent::__construct();
        if ($this->newsletter === null) {
            $this->newsletter = false;
        }
    }

    GETTER and SETTER ...
}

【问题讨论】:

  • 这似乎没问题。我唯一的猜测是注释没有被识别。尝试像他们在文档中那样做:symfony.com/doc/2.0/reference/constraints/UniqueEntity.html
  • 验证器不工作。我认为继承存在问题
  • “单表继承是一种继承映射策略,其中层次结构的所有类都映射到单个数据库表”。您似乎试图为每个班级使用不同的表格?
  • 不,我每个班级都使用同一张表
  • 我认为@Cerad 是对的。我的意思是,看看@Table 注释。他们都指向不同的名字......

标签: validation inheritance symfony doctrine-orm


【解决方案1】:

这是一个老问题,但人们仍然可能面临这个问题。这可能有助于并节省他们的时间。

问题是 UniqueEntityValidator 默认只接受当前(正在检查的)实体的存储库。换句话说,如果您提交合作伙伴,它只会检查合作伙伴条目。它不考虑其他实体,例如“single_table”继承映射中的买方或用户。

要解决您的问题,您只需将您的父类名称添加到您的注释 entityClass 属性中:

@DoctrineAssert\UniqueEntity(fields="username", message="Ce nom d'utilisateur est déjà utilisé, veuillez en choisir un autre.", groups={"registration", "account"}, entityClass="Antho\Test\CoreBundle\Entity\User")

这部分entityClass="Antho\Test\CoreBundle\Entity\User"实际上解决了你的问题。

在这种情况下,验证器将检查您的所有用户条目(也包括其子条目)。

【讨论】:

  • 谢谢@Tomas,这也是我的问题的解决方案。我有一个用户类和一个扩展用户类的成员类。当我想创建一个成员 obj 时,验证现在可以工作了。
  • 这应该是一个公认的答案,完全回答了问题
【解决方案2】:

我的两分钱。不要假装是正确的答案。

从子类中删除所有不需要的 @Table 并使字段可见 (protected)。我做了同样的事情(使用 Symfony 2.0.x),它就像一个魅力。

它与您的代码略有不同,这里的标签(或关键字)名称对于每个用户都是唯一的。但无论如何你都可以测试它:

/**
 * @ORM\Entity
 * @ORM\Table(
 *     name="meta",
 *     uniqueConstraints={
 *         @ORM\UniqueConstraint(columns={"name", "user_id", "type"})
 *     },
 *     indexes={
 *         @ORM\index(columns={"description"}),
 *         @ORM\index(columns={"type"})
 *     }
 * )
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"tag" = "Tag", "keyword" = "Keyword"})
 * @UniqueEntity(fields={"name", "user"})
 */
abstract class Meta
{
    protected $name;

    protected $user;
}

儿童班:

/**
 * @ORM\Entity
 */
class Tag extends Meta { }

/**
 * @ORM\Entity
 */
class Keyword extends Meta { }

【讨论】:

    猜你喜欢
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多