Я пытаюсь реализовать наследование таблиц классов в Doctrine. Мое приложение нуждается в пользовательском объекте, который используется для аутентификации пользователя через SymfonyСистема безопасности. Кроме того, моему приложению нужен особый пользователь, доктор.
Ниже вы можете найти выдержки из моих классов Entity.
Пользовательский класс (Base):
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Table(name="user")
* @UniqueEntity("email")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"user" = "User", "doctor" = "Doctor"})
*/
class User implements UserInterface, \Serializable, EquatableInterface {
/**
* @ORM\Id()
* @ORM\Column(name="id", type="uuid_binary")
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
* @JMS\Type("uuid")
*/
private $id;
// More fields that are used for authenticating a user (password, email, etc.)
}
Доктор Сущность расширяет Пользователь:
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\DoctorRepository")
* @ORM\Table(name="doctor")
* @ORM\HasLifecycleCallbacks()
*/
class Doctor extends User {
/**
* @ORM\Column(name="title", type="string")
*/
private $title;
// More fields that extend the User Entity
}
Странно я не могу ни удалить Users
ни Doctors
используя EntityManager’s remove()
метод, с которым у меня никогда не было проблем. Когда я использую метод, никакие ошибки не генерируются и не регистрируются, но экземпляр Entity остается в базе данных.
// This does not work. The user stays persisted in the database.
public function deleteUserAction($id) {
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('AppBundle:User')->find($id);
if(empty($user)) {
return new View('User not found', Response::HTTP_NOT_FOUND);
}
$em->remove($user);
$em->flush();
return new View('Deleted user', Response::HTTP_OK);
}
Я нашел обходной путь, используя ручной запрос для удаления объекта из базы данных.
// This works. The User is deleted from the database.
// If the user is a doctor the doctor referencing the user id is also
// deleted.
$qb = $em->createQueryBuilder()
->delete('AppBundle:User', 'u')
->where('u.id = :id')
->setParameter('id', $id, 'uuid_binary');
$qb->getQuery()->execute();
return $user;
Так что я мог бы просто использовать приведенный выше код, но я все еще хотел бы знать, что вызывает эту проблему?
Заранее спасибо!
Если вы не используете SchemaTool для генерации необходимого SQL, вы должны знать, что при удалении наследования таблиц классов используется свойство внешнего ключа.
ON DELETE CASCADE
во всех реализациях базы данных. Неспособность реализовать это самостоятельно приведет к мертвым строкам в базе данных.
Ссылка: Доктрина 2 документация:
Выполнение этого SQL-запроса, как показано ниже, может решить вашу проблему
ALTER TABLE user
ADD CONSTRAINT fk_user_1
FOREIGN KEY (id_user)
REFERENCES doctor (id_user)
ON DELETE CASCADE
ON UPDATE NO ACTION;
Может быть, если вы используете каскадные работы, посмотрите на эту документацию о доктринальном каскаде: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations