JPA - Can I create an Entity class, using an @DiscriminatorValue, that doesn't have its own table?
- by DaveyDaveDave
Hi - this is potentially a bit complex, so I'll do my best to describe my situation - it's also my first post here, so please forgive formatting mistakes, etc!
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.
Hopefully you're with me so far...
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 :)
EDIT: to correct my stacktrace.