这可能有点复杂,所以我会尽力描述我的情况 - 这也是我在这里的第一篇文章,所以请原谅格式错误等等!
我正在使用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,它存储在行动表。
希望你到目前为止和我在一起......
我正在从零开始创建一个新项目,所以我能做的很灵活,但显然希望从一开始就做到这一点!
我当前的实现有三个实体,其定义如下:
@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没有注册为实体,但我不知道如何做到这一点,因为它没有关联的表。
任何指针,无论是完整的答案还是谷歌的提示(我的想法都没有!),非常欢迎:)
编辑:纠正我的堆栈跟踪。
答案 0 :(得分:1)
您可以InheritanceType.SINGLE_TABLE
有多种方法可以为不同的分支提供多种继承类型。 See this question
答案 1 :(得分:1)
我认为我找到了一个适用于我的解决方案,我的实体现在看起来像:
@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类中引用'parent'表,我愚蠢地假设它不起作用。我的所有测试都是通过这个,它似乎正在工作;如果我将来需要添加其他动作,似乎会很高兴,使用不同的@DiscriminatorValue的SuppressAction副本按预期工作,所以我觉得我很高兴。