JPA. Can I create an Entity class using @DiscriminatorValue which doesn't have its own table?

this is potentially a little more complicated, so I'll do my best to describe my situation - this is also my first post here, so please forgive formatting errors etc.

I am using JPA with linked inheritance and a database structure that looks like this:

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 several different types of actions, all share ACTION_MAPPINGs referenced by the "parent" ACTION table. DELIVERY_CHANNEL_ACTION and OVERRIDE_ADDRESS_ACTION have additional extra data and map to ACTION using FK.

Real world, I also have a "suppress" action, but it doesn't have any extra data, so it doesn't have a matching table - all it needs is an ACTION_MAPPING which is stored in the ACTION table.

I hope you're still with me ...

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

In my current implementation that works, there are three concepts, which are 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 an Inheritance Strategy. DeliveryChannelAction and OverrideAddressAction also extend the action.

However, it seems wrong here that my Action class is the base class for these two actions, but also forms a concrete implementation for the suppress action.

So far this works, but at some point more actions are likely to be added, and there is every chance that some of them, like SUPPRESS, will not have additional data that starts to get complicated!

So ... what I would like to do in the object model world is to have the Action abstract and create a SuppressAction class that is empty except for @DiscriminatorValue ("SUPPRESS").

I tried to do what is described above, so by changing the 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 save 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 suppose depends on the SuppressAction not being registered as an entity, but I don't know how to do this, given that it has no associated table.

Any pointers, either full answers, or hints for things on google (I have no idea!) Are most welcome :)

EDIT: fix my stack.

+2


a source to share


2 answers


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

@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 referring to the "parent" table in my SuppressAction class, which I foolishly assumed would not work. All my tests pass with this and it seems to work; seems to be happy if I need to add other actions in the future, a copy of the SuppressAction, with a different @DiscriminatorValue function works as expected, so I think I'm happy.

+1


a source


You can with InheritanceType.SINGLE_TABLE



There are ways to have multiple types of inheritance for different branches. See this question .

+1


a source







All Articles