Я потратил некоторое время, пытаясь изобразить следующее отображение JPA / Hibernate с составными первичными ключами и внешними ключами (которые совместно используют 2 из 3 столбцов), но пока не радует :(.
Примеры таблицследовать (желтые ключевые столбцы содержат PK, синие ключевые столбцы включают FK):
И до сих пор я пришел со следующим отображением (который работает - он считывает данные из базы данных, но не может записывать какие-либо новые связи Party-AdditionalMessage из-за updatable = false, вставляемый-false):
...other imports...
import lombok.Getter;
import lombok.Setter;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(schema = "PARTY_TEMP_DATA", name = "PARTY")
@Getter
@Setter
public abstract class AbstractClientEntity implements PartyEntity, CreationTraceable, LastModificationTraceable {
@AttributeOverride(name = "id", column = @Column(name = "PARTY_ID"))
@AttributeOverride(name = "creationDateTime", column = @Column(name = "DATE_CREATED"))
@EmbeddedId
private PrimaryKey primaryKey;
@OneToMany(mappedBy = "client")
private List<AdditionalMessageEntity> additionalMessageList;
...other attributes follow...
}
...other imports...
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(schema = SCHEMA_NAME, name = "PERSON")
@PrimaryKeyJoinColumn(name = "PARTY_ID", referencedColumnName = "PARTY_ID")
@PrimaryKeyJoinColumn(name = "PARTY_CREATED", referencedColumnName = "DATE_CREATED")
@PrimaryKeyJoinColumn(name = "RETENTION_LEVEL_ID", referencedColumnName = "RETENTION_LEVEL_ID")
@Getter
@Setter
public class PersonClientEntity extends AbstractClientEntity {
@Column(name = "BIRTHDATE")
private LocalDate birthDate;
...other attributes...
}
...other imports...
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(schema = SCHEMA_NAME, name = "ADDITIONAL_MESSAGE")
@Getter
@Setter
public class AdditionalMessageEntity implements PartyEntity {
@AttributeOverride(name = "id", column = @Column(name = "ADDITIONAL_MESSAGE_ID"))
@EmbeddedId
private PrimaryKey primaryKey;
private String value;
@ManyToOne
@JoinColumn(name = "PARTY_ID", referencedColumnName = "PARTY_ID", insertable = false, updatable = false)
@JoinColumn(name = "PARTY_CREATED", referencedColumnName = "DATE_CREATED", insertable = false, updatable = false)
@JoinColumn(name = "RETENTION_LEVEL_ID", referencedColumnName = "RETENTION_LEVEL_ID", insertable = false, updatable = false)
private AbstractClientEntity client;
}
И, наконец, вот класс PrimaryKey:
...other imports...
import lombok.Data;
import lombok.NoArgsConstructor;
@Embeddable
@Data
@NoArgsConstructor
public class PrimaryKey implements Serializable {
/**
* Actual (unique) primary key.
*/
private Integer id;
/**
* Timestamp of the record creation, used for partitioning
*/
@Column(name = "PARTY_CREATED")
private LocalDateTime creationDateTime;
/**
* Data retention level, used for subpartitioning
*/
@Column(name = "RETENTION_LEVEL_ID")
private Integer retentionLevelId;
}
Я нашел похожий вопрос, который предлагает мне использовать аннотацию @MapsId (см. Hibernate - Составной первичный ключ содержитВнешний ключ ), но все мои попытки сделать это пока не увенчались успехом :( - основная проблема в том, что @MapsId можно применять только к одному свойству / один раз, в то время как у меня есть два общих столбца.
Любойхороший отзыв приветствуется