Подтвердить что ты не робот

Наследование класса таблицы Doctrine, когда один подкласс не имеет дополнительных атрибутов

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

/**
 * @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. Это работает (yay!), Но он чувствует себя крутым и уродливым, чтобы иметь дополнительную таблицу SQL, которая мне вообще не нужна.

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Возможно, это может помочь или добавить что-то новое. Это не то, как отвечать, а просто принимать понятия.

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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