当前位置: 首页 > 知识库问答 >
问题:

丑陋的Hibernate复合PK映射问题

充子航
2023-03-14

假设我有这些表:

表A在两个字段上有一个复合主键:

  • 员工ID(字符串)

表B也有一个复合主键,但在三个字段上:

  • 员工ID(字符串)
  • 交易ID(Long)
  • 日期(Date)

在表B中,员工ID和事务ID上有一个外键,称为“FK1”(为简单起见)。

由于表A中使用的复合id用于多个映射的Hibernate类,因此我创建了一个可以重用的类:

@Embeddable
public class EmployeeTransactionComposite {

    private String employeeId;
    private Long transactionId;

}

因此,映射到表A的类如下所示:

public ClassA implements Serializable {

    private EmployeeTransactionComposite id;
    // rest of fields

    @EmbeddedId
    public EmployeeTransactionComposite getId() {
        return id;
    }
}

映射到表B的类如下所示:

public ClassB implements Serializable {

    private ClassBCompositeId id;
    // fields

    @EmbeddedId
    public getId() {
        return this.id;
    }

    @Embeddable
    public class ClassBCompositeId implements Serializable {

        private EmployeeTransactionComposite composite;
        private Date date;

        @ManyToOne
    @ForeignKey(name="FK1")
        public EmployeeTransactionComposite getComposite() {
            return composite;
        }

        @Column(name="THEDATE")
        public Date getDate() {
            return date;
        }
    }
}

显然,如果它有效,我不会发布这个。它会像这样堆栈跟踪爆炸:

Caused By: java.lang.NullPointerException
at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1419)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1359)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1728)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1779)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:189)
Truncated. see log file for complete stacktrace

这是到遗留模式的映射,因此无法更改。有人能帮忙吗?

共有1个答案

孔君浩
2023-03-14

manytone从不指向主键类,而是始终指向实体。因此,此映射不正确:

@ManyToOne
@ForeignKey(name="FK1")
public EmployeeTransactionComposite getComposite() {
    return composite;
}

我建议不要在主键类中定义任何关联,而只定义基本列(或包含基本列的可嵌入项)。然后在实体本身中定义关联,并在此关联上使用@MapsId注释告诉Hibernate此关联使用的列与用于映射ID的列相同。

留档包含一个映射示例,它完全可以执行您正在尝试执行的操作:

嵌入id本身可以包含关联实体的主键。

@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @MapsId("userId")
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   @OneToOne User user;
}

@Embeddable
class CustomerId implements Serializable {
   UserId userId;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}
 类似资料:
  • 问题内容: 我在为某些实体设置jpa映射时遇到麻烦。我有一个如下定义的父实体。 然后,我有一个带有复合键的子实体,以及此表的主键的外键,如下所示: 我知道子实体不正确,但是我不确定如何将其设置为具有复合PK。我知道我需要设置一个PK类,但是当一个字段是父类的外键时,我不确定该怎么做。一旦设置好,父级将如何引用子级实体? 任何帮助表示赞赏。 问题答案: 这受JPA 2规范的 第2.4.1节“与派生身

  • 问题内容: 我有这个丑陋的代码: 如何摆脱多个if语句? 问题答案: 这对于您的情况更好。 (可选)您应该尽可能选择Switch Case 如果您已经分析了’v’的值,通常在大多数情况下都位于较低范围( <10),则无法添加。 根据您的分析,您还可以更改条件顺序。如果您知道大多数值都小于10,然后第二位的大多数值位于68-117之间,则可以相应地更改条件序列。 编辑:

  • 我有以下MySQL表。这里的思想是轨道和课程是主键。并且轨道中的一个航向可能依赖于“同一轨道”中的另一个航向,因此我在(,)上创建了一个复合FK 但我在“depends_on_course_id column”中得到的结果都是空的,我猜getTrackCourse方法的映射有问题,但我不知道是什么?非常感谢任何帮助。

  • 我正在使用Hibernate和JPA注释来映射我的类。当hibernate尝试映射这个类时,我遇到了一个问题 我的Social alStat类是: 我得到了这个错误: 我猜发生这种情况是因为我试图映射到一个基本类,但@ElementCollection注释不应该解决这个问题吗? 我的item类如下所示:

  • 问题内容: 我在这里搜索,但未找到任何类似的主题,因此我发布了一个新问题。 我正在使用现有数据库上的Hibernate。我们不允许更改表的结构和数据。该应用程序正在从数据库读取数据,并根据某种逻辑迁移到另一个数据存储。 现在的问题是关于复合PK映射。例如 表A具有复合PK。 表B也有一个复合PK,此复合PK的一部分是A的PK,此处也用作FK。 我尝试了几种方法,但都无济于事。谁能告诉一个有效的Hi

  • 我有实体类用户通过@IdClass注释使用复合键 复合键: 我将Spring数据与hibernate JPA一起使用。因此,我有回购接口: 我想通过具体姓名和姓氏列表从数据库中获取所有活跃用户。例如。我想使用这样的方法 如何通过Spring数据或JPQL查询此需求?