假设我有这些表格:
表A在两个字段上有一个复合主键:
表B还有一个复合主键,但在三个字段中:
在表B中,有一个名为" 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
这是传统架构的映射,因此无法进行更改。有人可以帮忙吗?
答案 0 :(得分:2)
ManyToOne从不指向主键类,但始终指向实体。因此,此映射不正确:
@ManyToOne
@ForeignKey(name="FK1")
public EmployeeTransactionComposite getComposite() {
return composite;
}
我建议不要在主键类中定义任何关联,只定义基本列(或包含基本列的嵌入列)。然后在实体本身中定义关联,并在此关联上使用@MapsId注释告诉Hibernate该关联使用与用于映射ID的列相同的列。
The documentation包含一个映射示例,它完全符合您的要求:
嵌入式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
}