Я пытался сопоставить многоуровневое наследование с doctrine2, вот UML:
Каждый класс отображает таблицу SQL, отображение выглядит следующим образом:
/**
* @Entity
* @Table(name="PERSONS")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="PERSON_TYPES", type="string")
* @DiscriminatorMap({"INSUREE" = "Insuree", "ADMIN" = "Admin"})
*/
abstract class Person extends Entity{}
/**
* @Entity
* @Table(name="INSUREES")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="INSUREE_TYPES", type="string")
* @DiscriminatorMap({"CUSTOMER" = "Customer", "THIRD_PARTY" = "ThirdParty"})
*/
abstract class Insuree extends Person{}
/**
* @Entity
* @Table(name="ADMINS")
*/
final class Admin extends Person implements User{}
/**
* @Entity
* @Table(name="CUSTOMERS")
*/
final class Customer extends Insuree implements User{}
/**
* @Entity
* @Table(name="EXPERTS")
*/
final class Expert extends Person{}
Когда я пытаюсь найти всех клиентов или любые другие конкретные классы, я получаю эту ошибку:
Uncaught Doctrine \ Instantiator \ Exception \ InvalidArgumentException: предоставленный класс "Insuree" является абстрактным и не может быть создан в ...
Я нашел проект на github, иерархия отображения которого похожа на мою и отлично работает:
https://github.com/paulandrieux/MultipleInheritanceSandbox/tree/master/src/Acme/DemoBundle/Entity
РЕДАКТИРОВАТЬ :
После помещения всех дискриминаторов в верхний класс (Person) Doctrine пропускает вставку данных в таблицу INSUREES, когда я пытаюсь сохранить нового клиента, поскольку я получаю эту ошибку:
Возникла исключительная ситуация при выполнении 'INSERT INTO CUSTOMERS (ID, ID_CARD, SEPA) VALUES (?,?,?)' С параметрами [10, "", ""]: SQLSTATE [23000]: Нарушение ограничения целостности: 1452 Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется (
aaa
.customers
, CONSTRAINTcustomers_ibfk_1
FOREIGN KEY (ID
) ССЫЛКИINSUREES
(ID
) НА КАСКАДЕ УДАЛЕНИЯ) "
Вот мой sql-скрипт CREATE TABLE:
CREATE TABLE IF NOT EXISTS PERSONS(
ID INTEGER NOT NULL AUTO_INCREMENT,
LAST_NAME VARCHAR(25) NULL,
FIRST_NAME VARCHAR(25) NULL,
ADDRESS VARCHAR(25) NULL,
CITY VARCHAR(25) NULL,
ZIP_CODE BIGINT(5) NULL,
TEL VARCHAR(13) NULL,
PERSON_TYPES ENUM("ADMIN","EXPERT","THIRD_PARTY","CUSTOMER"),
MAJ TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (ID)
);
CREATE TABLE IF NOT EXISTS INSUREES(
ID INTEGER NOT NULL UNIQUE,
BONUS_MALUS REAL(5,2) DEFAULT 1.0,
FOREIGN KEY (ID) REFERENCES PERSONS(ID) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS THIRD_PARTIES(
ID INTEGER NOT NULL UNIQUE,
COMPAGNY VARCHAR(128) NULL,
FOREIGN KEY (ID) REFERENCES INSUREES(ID) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS EXPERTS(
ID INTEGER NOT NULL UNIQUE,
RANK BIGINT(4) NULL,
FOREIGN KEY (ID) REFERENCES PERSONS(ID) ON DELETE CASCADE
)comment = "";
CREATE TABLE IF NOT EXISTS CUSTOMERS(
ID INTEGER NOT NULL UNIQUE,
ID_CARD VARCHAR(100),
SEPA VARCHAR(100),
FOREIGN KEY(ID) REFERENCES INSUREES(ID) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS ADMINS(
ID INTEGER NOT NULL UNIQUE,
ROLE VARCHAR(128) NULL,
FOREIGN KEY (ID) REFERENCES PERSONS(ID) ON DELETE CASCADE
);
1 ответ
Вам разрешено определять InheritanceType, DiscriminatorColumn и DiscriminatorMap только в самом верхнем классе Доктрина наследования таблиц-классов, которое в вашем случае является Человеком .
Я бы посоветовал следующее:
/**
* @Entity
* @Table(name="PERSONS")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="PERSON_TYPES", type="string")
* @DiscriminatorMap({
"INSUREE" = "Insuree",
"ADMIN" = "Admin",
"CUSTOMER" = "Customer",
"EXPERT" = "Expert"
})
*/
abstract class Person extends Entity{}
/**
* @Entity
* @Table(name="INSUREES")
*/
abstract class Insuree extends Person{}
Обновить:
Ваша схема базы данных должна выглядеть примерно так: где interface_task - это человек в вашем случае. Вы делаете это со всеми своими дочерними классами (и дочерними-дочерними классами), все они указывают на суперкласс, а идентификатор - это внешний ключ, указывающий на идентификатор суперкласса interface_task (человек в вашем случае)
Также убедитесь, что вы добавляете каскад при удалении к внешнему ключу, так что, если вы удаляете дочерний класс, также удаляется родительский класс в базе данных
Похожие вопросы
Новые вопросы
php
PHP — это широко используемый язык сценариев общего назначения с открытым исходным кодом, мультипарадигмальный, динамически типизированный и интерпретируемый, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.