以下示例显示了我尝试通过不是主键的唯一列组合来引用实体。
我想这样做,因为引用表包含了所引用的“复合辅助键”的所有必要组成部分,但不包含主键。
我该如何实现?(如果可能,而不是特定于Hibernate)
假设一个实体既有主键又有复合辅助键:
@Entity
@Table(name = "EXAMPLE_DATA",
uniqueConstraints = {
@UniqueConstraint(columnNames = {
"COMPOSITE_KEY_PART_1",
"COMPOSITE_KEY_PART_2"})
})
public class ExampleData {
@Id
@Column
private Long exampleDataId;
@Column(name = "COMPOSITE_KEY_PART_1")
private String compositeKeyPart1;
@Column(name = "COMPOSITE_KEY_PART_2")
private String compositeKeyPart2;
}
我想通过另一个组合键从另一个表中引用它:
@Entity
@Table(name = "EXAMPLE")
public class Example {
@Id
@Column
private Long exampleId;
@Column(name = "COMPOSITE_KEY_PART_1")
private String compositeKeyPart1; // of ExampleData
@Column(name = "COMPOSITE_KEY_PART_2")
private String compositeKeyPart2; // of ExampleData
@MayToOne
@JoinColumn(name = "COMPOSITE_KEY_PART_1", insertable = false, updatable = false)
@JoinColumn(name = "COMPOSITE_KEY_PART_2", insertable = false, updatable = false)
private ExampleData exampleData;
}
但是,这导致
org.hibernate.AnnotationException:
引用com.example.Example中的com.example.ExampleData的外键具有错误的列数。应该是1
@Embeddable
复合键我尝试使辅助密钥可嵌入
@Embeddable
public class CompositeKey implements Serializable {
@Column(name = "COMPOSITE_KEY_PART_1")
private String compositeKeyPart1;
@Column(name = "COMPOSITE_KEY_PART_2")
private String compositeKeyPart2;
}
并将其用作嵌入式对象:
@Entity
@Table(name = "EXAMPLE_DATA",
uniqueConstraints = {
@UniqueConstraint(columnNames = {
"COMPOSITE_KEY_PART_1",
"COMPOSITE_KEY_PART_2"})
})
public class ExampleData {
@Id
@Column
private Long exampleDataId;
@Embedded
private CompositeKey compositeKey;
}
但这会导致相同的异常:
org.hibernate.AnnotationException:
引用com.example.Example中的com.example.ExampleData的外键具有错误的列数。应该是1
@EmbeddedId
使用@EmbeddedId
而不是@Embedded
会导致多个键出现问题
org.hibernate.AnnotationException:
com.example.CompositeKey用作@EmbeddedId时,不得具有@Id属性:com.example.ExampleData.compositeKey
我真正使之起作用的唯一方法是删除主键,然后将组合键设为主键(但我不希望如此)
@Entity
@Table(name = "EXAMPLE_DATA")
public class ExampleData {
// @Id // removing this primary key is undesirable
@Column
private Long exampleDataId;
@EmbeddedId // This now becomes the primary key
private CompositeKey compositeKey;
}