我使用带有联合继承的 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,它是从“父”ACTION 表引用的。 DELIVERY_CHANNEL_ACTION 和 OVERRIDE_ADDRESS_ACTION 都有自己的额外补充数据,并通过 FK 映射到 ACTION。
现实世界中,我也有一个“抑制”操作,但是它自己没有任何补充数据,因此它没有相应的表 - 它需要的只是一个 ACTION_MAPPING,它存储在 ACTION 表中。
我正在从头开始创建一个新项目,因此我可以做的事情非常灵活,但显然希望从一开始就做好!
我当前的实现有效,具有三个松散定义的实体,如下所示:
@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。
但这里感觉不对的是,我的 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 没有注册为实体,但我不知道如何才能做到这一点,因为它没有关联的表。
任何指示,无论是完整的答案还是谷歌的提示(我没有想法!),非常欢迎。