情况
我有一个 Entity DiscriminatorColumn
,配置为单表继承:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE")
public class ContainerAssignment{
...
}
'ContainerAssignment' 引用了另一个实体:
@JoinColumn(name="CONTAINER_ID")
private Container container;
一个容器可能有ContainerAssignment
每个 TYPE 之一。这意味着表的主键由和ContainerAssignment
定义。CONTAINER_ID
TYPE
ContainerAssignment
有一些子类,例如
@Entity
@DiscriminatorValue("SOME_TYPE")
public class SomeTypeOfContainerAssignment extends ContainerAssignment{
...
}
SomeTypeOfContainerAssignment
给定的CONTAINER_ID
.
问题
如果我将 JPA 定义@Id
为 ContainerAssignment 表上的 Container,我可以这样做entityManager.find(SomeTypeOfContainerAssignment.class, containerId)
,这很棒。这与SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1 AND TYPE = 'SOME_TYPE';
. 它知道它需要在这里检查类型,因为@DiscriminatorValue("SOME_TYPE")
实体上的注释。
但是,这意味着从 Container 到 ContainerAssignment 的反向引用会中断,因为 Container 并不是真正的主键。例如,如果 Container 有一个@OneToOne(mappedBy=container) private SomeTypeOfContainerAssignment assignment;
,当您在容器中读取时,它将通过类似 的方式读取分配SELECT * FROM CONTAINER_ASSIGNMENT WHERE CONTAINER_ID = 1;
,而不进行类型检查。这给了它一个容器的所有分配,然后它看似随机地选择一个,可能是错误的类型,在这种情况下,它会抛出一个异常。
相反,如果我将@Id
ContainerAssignment 的 JPA 定义为使用容器和类型的复合 id,则对 ContainerAssignment 子类的引用可以正常工作。
但是,我不能这样做entityManager.find(SomeTypeOfContainerAssignment.class, containerId)
,因为 containerId 不是 id。我必须这样做entityManager.find(SomeTypeOfContainerAssignment.class, new MyPk(containerId, "SOME_TYPE"))
,这似乎是打败了点@DiscriminatorValue("SOME_TYPE")
。如果无论如何我必须在 find 上指定类型,我还不如只使用一个 ContainerAssignment Entity。
问题
有没有一种方法可以对单个表继承实体的子类进行工作引用,其中表上的主键在鉴别器列上是复合的,同时也能够EntityManager.find
仅通过主键的一部分来实现不是鉴别器?