2

假设我有这些表:

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

  • 员工 ID(字符串)
  • 交易 ID(长)

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

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

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

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

@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

这是到旧模式的映射,因此不可能进行更改。任何人都可以帮忙吗?

4

1 回答 1

2

ManyToOne 从不指向主键类,但始终指向实体。因此,这个映射是不正确的:

@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
}
于 2012-05-18T12:16:25.200 回答