【问题标题】:How to set up inheritage child entity as UserInterface with Symfony2如何使用 Symfony2 将继承子实体设置为 UserInterface
【发布时间】:2014-05-25 12:39:24
【问题描述】:

我有一个带有继承的数据库模型,使用的是 symfony2 的“类表继承”模型。

Employee 是一个抽象类,顶级继承模型。

秘书是扩展员工的孩子。 技术员也是扩展员工的孩子。

我正在构建一个应用程序,秘书可以在其中为技术人员管理一些事情,因此他们有一个包含一些表单等的管理面板。

SecretaryRepository 也是一个 UserProvider 接口,允许秘书通过应用程序进行身份验证。

我遇到的问题是身份验证查询不关心鉴别器...

身份验证SQL查询

的调试
SELECT e0_.*, s1_.*
FROM secretaries s1_
INNER JOIN employees e0_ ON s1_.id = e0_.id
WHERE e0_.removed_at IS NULL AND e0_.is_hidden = ? AND e0_.email = ?

我只是不明白如何管理秘书和员工之间的关系? 我应该手动包含从秘书到员工的外键吗?还是我应该手动处理身份验证查询中的鉴别器?

让我们看看我的模型的基础知识:

父级 Employee类

abstract class Employee
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=255, nullable=true)
     */
    protected $email;

    // [...] some other fields
}

孩子班秘书

class Secretary extends Employee
{
    /**
     * @var string
     *
     * @ORM\Column(name="password", type="string", length=255, nullable=true)
     * @Assert\NotBlank()
     */
    private $password;

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

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

    // [...] some other fields
}

UserProviderInterface 类SecretaryRepository

class SecretaryRepository extends EntityRepository implements UserProviderInterface
{
    public function loadUserByUsername($username)
    {
        $secretary = null;

        $qb = $this->_em->createQueryBuilder();

        $qb->select('s')
            ->from('HygieCoreBundle:Secretary', 's')
            ->where($qb->expr()->isNull('s.removedAt'))
            ->andWhere($qb->expr()->eq('s.isHidden', ':isHidden'))
            ->andWhere($qb->expr()->eq('s.email', ':email'))
            ->setParameter('isHidden', false)
            ->setParameter('email', $username)
        ;

        try {
            $secretary = $qb->getQuery()->getSingleResult();
        }
        catch (NoResultException $e) {
            throw new UsernameNotFoundException(sprintf('Aucune secrétaire ne possède l\'adresse e-mail : "%s".', $username), 0, $e);
        }

        return $secretary;
    }

    // [...] some other methods
}

问题很简单,INNER JOIN 子句不正确,因为它不使用从秘书到员工的外键,而是直接 id,也可以是技术人员 id!

这是我的表的一些行的导出:

INSERT INTO `technicians` (`id`, `speciality`) VALUES
(1, 'Communication')

INSERT INTO `employees` (`id`, `created_at`, `updated_at`, `removed_at`, `is_hidden`, `firstname`, `name`, `entityName`) VALUES
(1, '**sometime**', '**sometime**', NULL, 0, '**TechnicianFirstname**', '**TechnicianName**', 'technician'),
(2, '**sometime**', '**sometime**', NULL, 0, '**SecretaryFirstName**', '**SecretaryName**', 'secretary');

INSERT INTO `secretaries` (`id`, `password`, `salt`, `roles`) VALUES
(1, '**HashedPassword**', '**HashedSalt**', 'O:43:"Doctrine\\Common\\Collections\\ArrayCollection":1:{s:54:"\0Doctrine\\Common\\Collections\\ArrayCollection\0_elements";a:1:{i:0;s:10:"ROLE_ADMIN";}}');

ALTER TABLE `technicians` ADD CONSTRAINT `FK_1DCF6554BF396750` FOREIGN KEY (`id`) REFERENCES `employees` (`id`) ON DELETE CASCADE;

ALTER TABLE `secretaries` ADD CONSTRAINT `FK_ACB3412BF396750` FOREIGN KEY (`id`) REFERENCES `employees` (`id`) ON DELETE CASCADE;

【问题讨论】:

    标签: inheritance doctrine-orm symfony-2.4 class-table-inheritance doctrine-inheritance


    【解决方案1】:

    您直接从secretaries 表中选择数据,因此您不可能意外选择某些技术人员。使用此代码是安全的。

    如果您想在同一查询中同时选择秘书和技术人员,则需要鉴别器,即如果您的查询将从employees 表中选择。

    【讨论】:

    • 看起来很不可思议,但实际上,从Secretaries表中选择数据时,结果是Technician实例,由于Technician不是UserInterface而抛出错误......但是我无法解释,结果是个大问题!
    • 最后只是数据库中数据错误的问题,在一些结构变化之前插入...
    猜你喜欢
    • 2022-10-17
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    相关资源
    最近更新 更多