Mapping of composite primary keys and foreign keys with shared columns with JPA/Hibernate

爱⌒轻易说出口 提交于 2021-01-27 07:50:31

问题


I've spent a while trying to figure following JPA/Hibernate mapping with composite primary keys and foreign keys (which share 2 of 3 columns), but no joy so far :(.

The sample tables follow (yellow key columns comprise PK, blue key columns comprise FK):

And so far, I came with the following mapping (which kind of works - it reads data from the database, but can't write any new Party-AdditionalMessage associations because of the updatable=false, insertable-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;
}

And finally, here's PrimaryKey class:

...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;
}

I found a similar question, which suggests I should use @MapsId annotation (see Hibernate - Composite Primary Key contains Foreign Key) but all my attempts to do so failed so far :( - the main problem being that @MapsId can be only applied to one property/once, while I have two shared columns.

Any good tip appreciated

来源:https://stackoverflow.com/questions/58516280/mapping-of-composite-primary-keys-and-foreign-keys-with-shared-columns-with-jpa

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!