Наследование класса таблицы Doctrine, когда у одного подкласса нет лишних атрибутов - PullRequest
16 голосов
/ 12 августа 2011

У меня проблема с моим отображением. Я не могу заставить его работать. У меня есть абстрактный базовый класс, например:

/**
 * @Entity
 * @Table(name="actions")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"FOO" = "FooAction", "BAR" = "BarAction", ...})
 */
abstract class AbstractAction
{
    ...
}

У меня есть куча разных действий, все с разными полями. Например:

/**
 * @Entity
 * @Table(name="actions_foo")
 */
class FooAction extends AbstractAction
{
   ...
}

Но одно из моих действий (BarAction) не нуждается в дополнительных полях, кроме тех, которые предоставлены AbstractAction. Но как я могу отобразить это? Я попытался опустить @Table или использовать тот же @Table, что и AbstractAction, но безрезультатно.

/**
 * @Entity
 * @Table(name="actions")
 */
class BarAction extends AbstractAction
{
   ...
}

Пропуск @Table дает мне PDOException о пропущенной таблице BarAction. Использование @Table базового класса дает мне:

PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

Итак, как мне это отобразить?

Редактировать: Пока что я попробовал еще две вещи.

Я пытался удалить @Entity, а также @Table из BarAction в надежде, что для этого больше не потребуется таблица базы данных. Это не работает Вместо этого я получаю эту ошибку:

Doctrine\ORM\Mapping\MappingException: Class BarAction is not a valid entity or mapped super class.

Затем я попытался создать таблицу actions_bar в моей базе данных только с одним столбцом внешнего ключа id. Затем я сопоставил BarAction с ним. Это работает (ууу!), Но немного грустно и ужасно иметь дополнительную таблицу SQL, которая мне вообще не нужна.

Итак, все еще ищем лучший путь ...

Ответы [ 5 ]

2 голосов
/ 17 марта 2012

Вы используете joined модель наследования (наследование таблиц классов), которая использует отдельную таблицу для родителя и каждого потомка. Если вы не указали никаких полей в дочернем классе, Doctrine просто создаст таблицу, содержащую только поле идентификатора.

И родительский класс может использовать только один тип наследования: либо наследование таблицы классов, либо наследование одной таблицы.

В этом случае, если вы не хотите, чтобы в таблице была только колонка id, вам нужно изменить модель данных.

2 голосов
/ 11 февраля 2012

Может быть, это может помочь или добавить что-то новое. Это не то, как ответить, а просто понимание концепций.

Если вы думаете о классах и понимаете свою модель как: AbstractAction, FooAction и BarAction, то это, вероятно, связано с тем, что у вас могут быть одинаковые методы, реализованные по-разному для подклассов или для расширения некоторого родительского метода.

Если вы решите представлять эти классы с помощью таблиц и выберете «все в одной таблице с атрибутом дискриминатора», я думаю, у вас нет проблем. Для BarAction у вас будет регистрация с дискриминацией = "BarAction", которая будет представлена ​​классом сущности BarAction.php.

С другой стороны, если вы решите использовать другую таблицу, я считаю, что вам нужна одна таблица на «класс». Таблица для BarAction будет связываться только с полем ID для AbstractAction, но она необходима для "классификации" (или различения) ваших данных как FooAction.

В целом, я думаю, что три таблицы, представляющие три класса, являются хорошим решением, хотя таблица BarAction просто содержит «ссылку» на родительскую таблицу.

0 голосов
/ 14 мая 2019

Немного позднего ответа, но это может быть полезно для других, задающих этот вопрос.

Сделайте класс 'AbstractAction' конкретным и добавьте для него отображение на карте дискриминатора (вы, вероятно, захотите переименовать его в этот момент)

 * @DiscriminatorMap({"ABSTRACT" = "AbstractAction", "FOO" = "FooAction", "BAR" = "BarAction", ...})
 */
class AbstractAction
{

Затем вы должны использовать эту таблицу для строк, которые не нуждаются в дополнительных столбцах

0 голосов
/ 06 апреля 2012

Я также столкнулся с этой проблемой, но я только добавил некоторые фиктивные свойства в свою унаследованную сущность, думая, что это может быть полезно в любое время.Я знаю, что это не идеальная идея, но это помогло мне сохранить целостность моей модели данных и дать мне возможность иметь собственные свойства унаследованных объектов в будущем.

0 голосов
/ 04 марта 2012

Я думаю, вам не нужно вручную создавать таблицу в вашей базе данных.

У меня почти такая же структура, что я позволю Doctrine (2.3) выполнять свою работу.Вы должны поместить @Entity et @Table в каждый подкласс.Ошибка Недопустимый номер параметра: количество связанных переменных не соответствует количеству токенов, может быть не связано.Это может быть проблема с кешем, вы пытались очистить его?

...