JPA - Могу ли я создать класс Entity, используя @DiscriminatorValue, у которого нет собственной таблицы? - PullRequest
2 голосов
/ 26 апреля 2010

это потенциально немного сложно, поэтому я сделаю все возможное, чтобы описать мою ситуацию - это также мой первый пост здесь, поэтому, пожалуйста, прости за ошибки форматирования и т. Д.!

Я использую JPA с объединенным наследованием и структурой базы данных, которая выглядит следующим образом:

ACTION
---------
ACTION_ID
ACTION_MAPPING_ID
ACTION_TYPE

DELIVERY_CHANNEL_ACTION
--------------------------
ACTION_ID
CHANNEL_ID

OVERRIDE_ADDRESS_ACTION
--------------------------
ACTION_ID
(various fields specific to this action type)

Итак, на простом английском языке, у меня есть несколько различных типов действий, все имеют общий ACTION_MAPPING, на который ссылается таблица 'parent' ACTION. DELIVERY_CHANNEL_ACTION и OVERRIDE_ADDRESS_ACTION имеют дополнительные дополнительные данные и отображаются в ACTION с помощью FK.

Реально, у меня также есть действие «подавить», но у него нет собственных дополнительных данных, поэтому у него нет соответствующей таблицы - все, что ему нужно, это ACTION_MAPPING, который хранится в Таблица ДЕЙСТВИЙ.

Надеюсь, ты пока со мной ...

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

Моя текущая реализация, которая работает, имеет три сущности, которые определены следующим образом:

@Entity
@Table(name="ACTION")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorValue("SUPPRESS")
public class Action

@Entity
@Table(name="DELIVERY_CHANNEL_ACTION")
@DiscriminatorValue("DELIVERY_CHANNEL")
public class DeliveryChannelAction extends Action

@Entity
@Table(name="OVERRIDE_ADDRESS_ACTION")
@DiscriminatorValue("OVERRIDE_ADDRESS")
public class OverrideAddressAction extends Action

То есть - у меня есть конкретный базовый класс, Action, со стратегией наследования Joined. DeliveryChannelAction и OverrideAddressAction расширяют действие.

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

В настоящее время это работает, но в какой-то момент, вероятно, будет добавлено больше действий, и есть все шансы, что некоторые из них, такие как SUPPRESS, не будут иметь никаких дополнительных данных, которые станут трудными!

Итак ... что я хотел бы сделать в мире объектной модели - это сделать Action абстрактным и создать класс SuppressAction, который будет пустым, кроме @DiscriminatorValue ("SUPPRESS").

Я пытался делать именно то, что описано выше, поэтому изменил действие на:

@Entity
@Table(name="ACTION")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Action

и создание:

@DiscriminatorValue("SUPPRESS")
public class SuppressAction extends Action

но не повезло - кажется, что он отлично работает для DeliveryChannelAction и OverrideAddressAction, но когда я пытаюсь создать SuppressAction и сохранить его, я получаю:

java.lang.IllegalArgumentException: Object: com.mypackage.SuppressAction[actionId=null] is not a known entity type.
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4147)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:368)
    at com.mypackage.test.util.EntityTestUtil.createSuppressAction(EntityTestUtil.java:672)
    at com.mypackage.entities.ActionTest.testCRUDAction(ActionTest.java:27)

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

Любые указатели, либо полные ответы, либо подсказки для Google (у меня нет идей!), Приветствуются:)

РЕДАКТИРОВАТЬ: исправить мою трассировку стека.

Ответы [ 2 ]

1 голос
/ 26 апреля 2010

Я думаю, что нашел решение, которое должно работать для меня, теперь мои сущности выглядят так:

@Entity
@Table(name="ACTION")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorValue("SUPPRESS")
public abstract class Action

@Entity
@Table(name="DELIVERY_CHANNEL_ACTION")
@DiscriminatorValue("DELIVERY_CHANNEL")
public class DeliveryChannelAction extends Action

@Entity
@Table(name="OVERRIDE_ADDRESS_ACTION")
@DiscriminatorValue("OVERRIDE_ADDRESS")
public class OverrideAddressAction extends Action

@Entity
@Table(name="ACTION")
@DiscriminatorValue("SUPPRESS")
public class SuppressAction extends Action

Итак, по сути, все, чего мне не хватало, - это ссылки на «родительскую» таблицу в моем классе SuppressAction, которая, как я и думал по глупости, не сработает. Все мои тесты проходят с этим, и, кажется, работает; Похоже, что я буду счастлив, если в будущем мне понадобится добавить другие Действия, копию SuppressAction с другим @DiscriminatorValue, как и ожидалось, поэтому я думаю, что я счастлив.

1 голос
/ 26 апреля 2010

Вы можете, с помощью InheritanceType.SINGLE_TABLE

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...