Приведенные ниже примеры показывают, что я пытался ссылаться на сущность по уникальной комбинации столбцов, которая не является ее первичным ключом .
Я хочу сделать это таким образом, потому что таблица ссылоксодержит все необходимые составляющие указанного «составного вторичного ключа», но не содержит первичного ключа.
Как мне этого достичь? (если возможно, не привязываясь к 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.ExampleData из com.example.Пример имеет неправильный номер столбца.должно быть 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.ExampleData из com.example.Exampleимеет неправильный номер столбца.должно быть 1
Использование @EmbeddedId
Использование @EmbeddedId
вместо просто @Embedded
приводит к проблемам с несколькими ключами
org.hibernate.AnnotationException:
com.example.CompositeKey не должен иметь свойств @Id при использовании в качестве @EmbeddedId: 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;
}