【问题标题】:JPA - Error trying to map a shared composite key using IdClass instead of an EmbeddedIdJPA - 尝试使用 IdClass 而不是 EmbeddedId 映射共享复合键时出错
【发布时间】:2013-11-08 21:00:02
【问题描述】:

一旦您看到我在代码块中发布的复合键和使用它们的实体,请参阅我需要在数据库中为 Address 实体提供的下一个伪表:

地址表:

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 是一个枚举

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

映射错误在哪里?

提前谢谢你!

【问题讨论】:

    标签: java jpa orm mapping eclipselink


    【解决方案1】:

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

    像这样:

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

    【讨论】:

    • 感谢您的回复,但这并不是因为枚举类型通过 ORDINAL 赋值隐式持久化。
    【解决方案2】:

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

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

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

    2:主键通常以表名命名,后跟ID(永远不要只使用'ID'作为名称)。

    示例: 地址 addressID 长主键

    3:您称为主键的其他字段可能应该是引用其他表的主键的外键(在其后键入长 ID)。

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

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

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

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

    您可以联系您友好的邻居数据库管理员以帮助创建您的数据库架构。

    【讨论】:

    • 感谢您的回复,但这不是我想要的。你推荐的那些东西我很感激,但它并没有回答我的问题(正如你在开头所说的那样)。我发布的这个问题只是 JPA 的一个映射问题,对于一个已经存在但我无法更改的数据库,该数据库已经很好地规范化并且那些复合 Id 是唯一的,并且需要这样,架构很好,我只需要将它映射到 JPA。再次感谢您!
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 2012-08-19
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      相关资源
      最近更新 更多