У меня есть объект с 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 @Id
ContainerAssignment как составной идентификатор, используя контейнер и тип, ссылки на подклассы ContainerAssignment работают нормально.
Однако я не могу выполнить entityManager.find(SomeTypeOfContainerAssignment.class, containerId)
, потому что containerId не является идентификатором. Мне нужно выполнить entityManager.find(SomeTypeOfContainerAssignment.class, new MyPk(containerId, "SOME_TYPE"))
, что, похоже, противоречит @DiscriminatorValue("SOME_TYPE")
. С тем же успехом я мог бы просто использовать одну сущность ContainerAssignment, если мне все равно нужно указать тип при поиске.
Есть ли способ иметь рабочие ссылки на подклассы объекта наследования одной таблицы, где первичный ключ таблицы является составным в столбце дискриминатора, а также иметь возможность EntityManager.find
только часть(и) первичного ключа, которые не являются дискриминатором?