JPA-我可以使用@DiscriminatorValue创建没有自己的表的Entity类吗? [英] JPA - Can I create an Entity class, using an @DiscriminatorValue, that doesn't have its own table?

查看:84
本文介绍了JPA-我可以使用@DiscriminatorValue创建没有自己的表的Entity类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有联合继承和如下数据库结构的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")之外都是空的. /p>

我已经尝试完全按照上面的描述进行操作,因此将Action更改为:

@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的提示(我没主意!),都很受欢迎.

解决方案

我想我找到了一个适合我的解决方案,我的实体现在看起来像:

@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可以按预期工作,所以我觉得很高兴.

I'm using JPA with joined inheritance and a database structure that looks like:

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)

So, in plain English, I have multiple different types of action, all share an ACTION_MAPPING, which is referenced from the 'parent' ACTION table. DELIVERY_CHANNEL_ACTION and OVERRIDE_ADDRESS_ACTION both have extra, supplementary data of their own, and are mapped to ACTION with a FK.

Real-world, I also have a 'suppress' action, but this doesn't have any supplementary data of its own, so it doesn't have a corresponding table - all it needs is an ACTION_MAPPING, which is stored in the ACTION table.

I'm creating a new project from scratch, so am pretty flexible in what I can do, but obviously would like to get it right from the outset!

My current implementation, which works, has three entities loosely defined as follows:

@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

That is - I have a concrete base class, Action, with a Joined inheritance strategy. DeliveryChannelAction and OverrideAddressAction both extend Action.

What feels wrong here though, is that my Action class is the base class for these two actions, but also forms the concrete implementation for the suppress action.

For the time being this works, but at some point more actions are likely to be added, and there's every chance that some of them will, like SUPPRESS, have no supplementary data, which will start to get difficult!

So... what I would like to do, in the object model world, is to have Action be abstract, and create a SuppressAction class, which is empty apart from having a @DiscriminatorValue("SUPPRESS").

I've tried doing exactly what is described above, so, changing Action to:

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

and creating:

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

but no luck - it seems to work fine for DeliveryChannelAction and OverrideAddressAction, but when I try to create a SuppressAction and persist it, I get:

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)

which I assume is down to the fact that SuppressAction isn't registered as an entity, but I don't know how I can do that, given that it doesn't have an associated table.

Any pointers, either complete answers or hints for things to Google (I'm out of ideas!), most welcome.

解决方案

I think I found a solution that should work for me, my entities now look like:

@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

So, basically all I was missing was referencing the 'parent' table in my SuppressAction class, which I had foolishly assumed wouldn't work. All my tests are passing with this, and it seems to be working; it seems like it will be happy if I need to add other Actions in the future, a copy of SuppressAction, with a different @DiscriminatorValue works as expected, so I think I'm happy.

这篇关于JPA-我可以使用@DiscriminatorValue创建没有自己的表的Entity类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆