DiscriminatorColumn как часть первичного ключа/идентификатора

Ситуация

У меня есть объект с DiscriminatorColumn, сконфигурированный для наследования одной таблицы:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE")
public class ContainerAssignment{
...
}

'ContainerAssignment' имеет ссылку на другой объект:

@JoinColumn(name="CONTAINER_ID")
private Container container;

Контейнер может иметь по одному ContainerAssignmentкаждого ТИПА. Это означает, что первичный ключ таблицы ContainerAssignmentопределяется CONTAINER_IDи TYPE.

ContainerAssignmentимеет несколько подклассов, например.

@Entity
@DiscriminatorValue("SOME_TYPE")
public class SomeTypeOfContainerAssignment extends ContainerAssignment{
...
}

Будет только один экземпляр SomeTypeOfContainerAssignmentдля данного CONTAINER_ID.

Проблема

Если я определяю JPA @Idкак просто Container в таблице ContainerAssignment, я могу выполнить entityManager.find(SomeTypeOfContainerAssignment.class, containerId), который отлично. Это запускает что-то вроде SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1 AND TYPE = 'SOME_TYPE';. Он знает, что здесь нужна проверка TYPE из-за аннотации @DiscriminatorValue("SOME_TYPE")на Entity.

Однако это означает, что обратные ссылки из Container в ContainerAssignment прерываются, поскольку Container на самом деле не является первичным ключом.Например, если у контейнера есть @OneToOne(mappedBy=container) частное назначение SomeTypeOfContainerAssignment;, когда вы читаете в контейнере, он будет читать в назначении что-то вроде SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1;, без проверки типа. Это дает ему все назначения для контейнера, а затем он выбирает одно, казалось бы, случайное, потенциально неправильного типа, и в этом случае генерирует исключение.

Если вместо этого я определяю JPA @IdContainerAssignment как составной идентификатор, используя контейнер и тип, ссылки на подклассы ContainerAssignment работают нормально.

Однако я не могу выполнить entityManager.find(SomeTypeOfContainerAssignment.class, containerId), потому что containerId не является идентификатором. Мне нужно выполнить entityManager.find(SomeTypeOfContainerAssignment.class, new MyPk(containerId, "SOME_TYPE")), что, похоже, противоречит @DiscriminatorValue("SOME_TYPE"). С тем же успехом я мог бы просто использовать одну сущность ContainerAssignment, если мне все равно нужно указать тип при поиске.

Вопрос

Есть ли способ иметь рабочие ссылки на подклассы объекта наследования одной таблицы, где первичный ключ таблицы является составным в столбце дискриминатора, а также иметь возможность EntityManager.find только часть(и) первичного ключа, которые не являются дискриминатором?

10
задан Bruno Kim 14 December 2012 в 16:58
поделиться