robert trudel
robert trudel

Reputation: 5749

Reuse a composite key for a child + a new field

I use spring boot, with jpa (hibernate) and postgresql

I use composite key.

@Entity
@IdClass(SamplingsPK.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {

    @Id
    @GeneratedValue
    private Integer id;

    @Id
    private int year;

    @OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Samples> samples = new ArrayList<>();
   ...
}

public class SamplingsPK implements Serializable {

    private Integer id;

    private int year;

    public SamplingsPK(Integer id, int year) {
        this.id = id;
        this.year=year;
    }

    private SamplingsPK(){

    } 

    @PrePersist
    public void prePersist() {
        year = LocalDate.now().getYear();
    }
}   

@Entity
public class Samples {
    @Id
    @SequenceGenerator(name = "samples_id_seq", sequenceName = "samples_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "samples_id_seq")
    private Integer id;

    private String sampleLetter;

    @ManyToOne
        @JoinColumns({
            @JoinColumn(name = "sampling_id", referencedColumnName = "id"),
            @JoinColumn(name = "sampling_year", referencedColumnName = "year")
        })
private Samplings sampling;

}

That work fine

Instead of having an sequence in samples, I would like to have a composite key... SamplingsPK + sampleLetter.

Is it possible to do it, how to save a sample?

Upvotes: 1

Views: 362

Answers (1)

Brian Vosburgh
Brian Vosburgh

Reputation: 3276

This is a "derived identity", so Samples could be mapped with an @IdClass like this:

@Entity
@IdClass(SamplesPK.class)
public class Samples {
    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "sampling_id", referencedColumnName = "id"),
        @JoinColumn(name = "sampling_year", referencedColumnName = "year")
    })
    private Samplings sampling;

    @Id
    private String sampleLetter;
}

public class SamplesPK {
    SamplingsPK sampling; // matches name of attribute and type of Samplings PK
    String sampleLetter; // matches name and type of attribute
}

Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

Upvotes: 1

Related Questions