如何在JPA中设置@EmbeddedId的反向引用

时间:2011-01-08 16:21:49

标签: java jpa eclipselink

是否有人知道是否可以在JPA @EmbeddedId内建立反向引用。

例如,有一个表格的实体

@Entity
public class Entity1 {
    @Id
    @GeneratedValue
    private String identifier;

    private Entity1 relationToEntity1;
    //Left out the getters and setters for simplicity
}

第二个具有复杂嵌入式ID的实体。第二个实体的一部分是对其父实体的引用。像这样:

@Entity
public class Entity2 {
    @EmbeddedId private Entity2Identifier id;
    //Left out the getters and setters for simplicity.
}

@Embedabble
public class Entity2Identifier {
    private String firstPartOfIdentifier;
    private Entity1 parent;
    //Left out the getters and setters for simplicity.
}

当我尝试通过JPA(Implementation is EclipseLink)将这样的构造保存到数据库时,我得到了几种形式的例外:

Exception [EclipseLink-93] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT): 
org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The table [ENTITY1] is not present in this descriptor.
Descriptor: RelationalDescriptor(test.Entity2 --> [DatabaseTable(ENTITY2)])

Exception [EclipseLink-93] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT): org.eclipse.persistence.exceptions.DescriptorException Exception Description: The table [ENTITY1] is not present in this descriptor. Descriptor: RelationalDescriptor(test.Entity2 --> [DatabaseTable(ENTITY2)])

有人遇到这样的问题并有解决方案吗?

2 个答案:

答案 0 :(得分:4)

您要找的是衍生ID。如果您使用的是JPA 2.0,则以下内容将起作用。你真的不希望整个父母成为PK的一部分,只是父母的PK。

@Entity
public class Entity1 {
    @EmbeddedId
    private ParentId identifier;

    @OneToOne(mappedBy="relationToEntity1")
    private Entity2 relationToEntity2;

    //Left out the getters and setters for simplicity
}

@Entity
public class Entity2 {
    @EmbeddedId private Entity2Identifier id;
    //Left out the getters and setters for simplicity.

    @MapsId("parentId")
    @OneToOne
    private Entity1 parent;

}

@Embedabble
public class Entity2Identifier {
    private String firstPartOfIdentifier;
    private ParentId parentId;
    //Left out the getters and setters for simplicity.
}

答案 1 :(得分:1)

@EmbeddedId注释不允许复合标识类中的关系。来自EmbeddedId JavaDoc

  

不支持嵌入式id类中定义的关系映射。

我知道您希望Entity2Identifier包含父级的密钥,但在您的示例中,您创建的是与整个对象的关系,而不仅仅是包含父级的主键。即使这种结构有效,您也可以将复合键建立为父级的主键,而不是父级的整个状态。

如果您只是想找到一种简单的方法来建立双向关系,您可以使用@OneToOne注释和mappedBy属性:

@Entity
public class Entity1 {
    @Id
    @GeneratedValue
    private String identifier;

    @OneToOne(mappedBy="relationToEntity1")
    private Entity2 relationToEntity2;
    ...
}

@Entity
public class Entity2 {

    @OneToOne
    private Entity1 relationToEntity1;
    ...
}

通过这组注释,JPA提供程序将正确处理Entity1.relationToEntity2Entity2.relationToEntity1作为双向关系。您可能还希望覆盖默认的级联行为(无)以及默认的孤立删除行为(无)。有关详细信息,请参阅JavaDoc