JPA - 尝试使用IdClass而不是EmbeddedId映射共享复合键时出错

时间:2013-10-29 15:37:34

标签: java jpa orm mapping eclipselink

一旦你看到我在代码块中发布的复合密钥和使用它们的实体,请参考我需要在数据库中为地址实体提供的下一个伪代码:

地址表:

ADDRESS
-------------------------------
DOCUMENTTYPE    INT2         PK
DOCUMENTNR      VARCHAR(10)  PK
ALIAS           VARCHAR(20)  PK
FULLADDRESS     VARCHAR(100)
...

实体&复合键:

@Embeddable
public class Document implements Serializable {
    private DocumentType  documentType;
    private String        documentNr;
    ...

@Entity
@IdClass(Document.class)
public class Person {
    @Id
    private DocumentType  documentType;
    @Id
    private String        documentNr;
    private String        fullName;
    ...

@Embeddable
public class AddressId implements Serializable {
    private DocumentType  documentType;
    private String        documentNr;
    private String        alias;
    ...

@Entity
@IdClass(AddressId.class)
public class Address {
    @Id
    @ManyToOne
    private Person        person;
    @Id
    private String        alias;
    private String        fullAddress;
    ...

注意: DocumentType 枚举

好吧,我正在尝试为地址实体设置映射,但它不起作用,我不知道为什么。它一直在说(EclipseLink)我遇到名称和类型不匹配的问题。我不明白为什么如果 AddressId IdClass没有alias属性(当然也没有 Address 实体),那么它就像魅力一样,以及使用完整的 AddressId IdClass(使用alias属性)但使用EmbeddedId。我需要的是像我发布的那样拥有地址实体。

映射错误在哪里?

提前谢谢!

3 个答案:

答案 0 :(得分:0)

我认为您必须将@Enumerated(EnumType.STRING)添加到enum字段

像这样:

@Id
@Enumerated(EnumType.STRING)
private DocumentType  documentType;

答案 1 :(得分:0)

我无法直接回答你的问题。但是,这是一个可能有帮助的观察结果:

我认为您的数据库架构在将其映射到Java之前需要工作。以下是一些建议:

1:每个数据库表应该只有一个主键(通常是long类型),主键应该没有业务含义。任何地方都没有复合键由于没有复合键,原始问题不再是问题。

2:主键通常以带有ID的表名命名(从不使用'ID'作为名称)。

实施例:  地址  addressID long primaryKey

3:您调用主键的其他字段应该是引用其他表主键的外键(类型为long,后面带有ID)。

4:您需要正确规范化数据库表。示例:列'fullAddress'可能应该分为streetAddress,city,stateID,countryID,zipcode。另一个例子:ADDRESS表应该只包含地址信息。为什么它有DOCUMENTTYPE?这与地址有什么关系?

5:应清楚地理解数据库表和列的名称。 “DOCUMENTNR”栏对我没有任何意义。

6:您的数据库表和列应该是nowns,它们通常应该映射到具有相同名称的java类。相反,你有一个名为AddressId的类,它显然映射到地址数据库表。将类重命名为Address。

7:您需要确定哪些列是唯一的而不是可空的。

您可以与友好的邻居数据库管理员联系,以获取有关创建数据库架构的帮助。

答案 2 :(得分:0)

地址的派生ID必须包含来自person的id,即文档而不是其组件。 http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/mappedbyid显示了一些示例,但更多的是针对嵌入式,但idclasses的概念是相同的。尝试

public class AddressId implements Serializable {
    private Document person;
    private String   alias;