Note that there are some explanatory texts on larger screens.

plurals
  1. PODiscriminatorColumn as part of primary key / id
    primarykey
    data
    text
    <h1>Situation</h1> <p>I have an Entity with a <code>DiscriminatorColumn</code>, configured for single table inheritance:</p> <pre><code>@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TYPE") public class ContainerAssignment{ ... } </code></pre> <p>'ContainerAssignment' has a reference to another Entity:</p> <pre><code>@JoinColumn(name="CONTAINER_ID") private Container container; </code></pre> <p>A container may have one <code>ContainerAssignment</code> of each TYPE. This means that the primary key of the <code>ContainerAssignment</code> table is defined by the <code>CONTAINER_ID</code> and the <code>TYPE</code>.</p> <p><code>ContainerAssignment</code> has some subclasses e.g.</p> <pre><code>@Entity @DiscriminatorValue("SOME_TYPE") public class SomeTypeOfContainerAssignment extends ContainerAssignment{ ... } </code></pre> <p>There will only be a single <code>SomeTypeOfContainerAssignment</code> instance for a given <code>CONTAINER_ID</code>.</p> <h1>Problem</h1> <p>If I define the JPA <code>@Id</code> as just the Container on the ContainerAssignment table, I can do <code>entityManager.find(SomeTypeOfContainerAssignment.class, containerId)</code>, which is great. This runs something along the lines of <code>SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1 AND TYPE = 'SOME_TYPE';</code>. It knows it needs the TYPE check in here, because of the <code>@DiscriminatorValue("SOME_TYPE")</code> annotation on the Entity.</p> <p>However, this means that the back references from Container to ContainerAssignment breaks as Container is not really the primary key. For example, if Container has a <code>@OneToOne(mappedBy=container) private SomeTypeOfContainerAssignment assignment;</code>, when you read in a container, it will read in the assignment by something like <code>SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1;</code>, without the type checking. This gives it all assignments for a container, and then it picks one seemingly at random, potentially of the wrong type, in which case, it throws an exception.</p> <p>If instead, I define the JPA <code>@Id</code> of ContainerAssignment as a composite id using container and type, references to the sub-classes of ContainerAssignment work fine.</p> <p>However, I cannot do <code>entityManager.find(SomeTypeOfContainerAssignment.class, containerId)</code>, because containerId is not the id. I have to do <code>entityManager.find(SomeTypeOfContainerAssignment.class, new MyPk(containerId, "SOME_TYPE"))</code>, which seems to defeate the point of <code>@DiscriminatorValue("SOME_TYPE")</code>. I might as well just use a single ContainerAssignment Entity if I have to specify type on find anyway.</p> <h1>Question</h1> <p>Is there a way to have working references to sub-classes of a single table inheritance Entity where the primary key on the table is composite on the discriminator column, whilst also being able to <code>EntityManager.find</code> by just the part(s) of the primary key which are not the discriminator?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload