I use jpa and hibernate, I try to save an Icomposite pk
public class EmbedddedSamplesKey implements Serializable {
private Integer id;
private int year;
...
}
@Entity
@IdClass(EmbedddedSamplesKey.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
@Id
@GeneratedValue
private Integer id;
@Id
private int year;
@OneToMany(mappedBy = "sampling", cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Samples> samples = new ArrayList<>();
public void addSample(Samples sample) {
samples.add(sample);
sample.setSampling(this);
}
public void removeSample(Samples sample) {
samples.remove(sample);
sample.setSampling(null);
}
...
}
@Entity
public class Samples extends BaseEntity {
@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 letter;
@ManyToOne
private Samplings sampling;
...
}
When I save I do
Samplings sampling = new TraditionalSamplings();
samplings.setYear(LocalDate.now().getYear());
Samples sample = new Samples()
sample.setSampleLetter("A");
samplings.addSample(sample);
samplingRepository.save(samplings);
Samplings and samples are saved
but in samples table, sample_id_sampling_year there are not value
I was thinking theses values should be put automatically by hibernate?
vlad
2
@IdClass
and @GeneratedValue
works properly in Hibernate. We have a test in the documentation folder that proves it.
The problem in your code comes from this mapping:
@ManyToOne
private Samplings sampling;
The Samples
entity will expect a samplings_id FK to reference the Samplings
table PK. But the Samplings
table has a composite identifier.
Therefore, you need to use @JoinColumns
:
@ManyToOne
@JoinColumns({
@JoinColumn(
name = "samplings_id",
referencedColumnName = "id"),
@JoinColumn(
name = "samplings_year",
referencedColumnName = "year")
})
private Samplings sampling;
For more details about mapping composite identifiers, check out the User Guide.
just modified
@ManyToOne
@JoinColumns({
@JoinColumn(name = "sampling_id", referencedColumnName = "id"),
@JoinColumn(name = "sampling_year", referencedColumnName = "year")})
private Samplings sampling;
because field are sampling_id an sampling_year… so no “s”…
but still no value
vlad
4
Show us the SQL log that gets executed along with the bind parameter values logged as well.
Hibernate:
select
nextval ('permacon.hibernate_sequence')
Hibernate:
select
nextval ('permacon.samples_id_seq')
Hibernate:
select
nextval ('permacon.samples_id_seq')
Hibernate:
select
nextval ('permacon.samples_id_seq')
Hibernate:
select
nextval ('permacon.samples_id_seq')
Hibernate:
select
nextval ('permacon.samples_id_seq')
Hibernate:
insert
into
permacon.samplings
(available_for_test, build_date, reception_date, dtype, id, year)
values
(?, ?, ?, 'TraditionalSamplings', ?, ?)
Hibernate:
insert
into
permacon.samples
(created_at, updated_at, sample_letter, sampling_id, sampling_year, id)
values
(?, ?, ?, ?, ?, ?)
dtype id year available_for_test build_date reception_date
TraditionalSamplings 59 2018 true 2018-05-27 2018-05-27
id created_at updated_at sample_letter sampling_id sampling_year
55 2018-05-27 09:16:02
vlad
6
Try changing the cascade to CascadeType.ALL
:
@OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
It might be that Spring Data called merge
instead of persist
because the composite identifier is an actual Object and not a null reference.
you got it, thank
you know if that could possible to use in sample
idClass + sample_letter like a primary key?
vlad
8
I’m glad it worked.
I don’t understand your last question. Is it that you want the composite identifer to include one more column?
In sampling I use a composite key for the primary key
What I would like to do is to you use this composite key + another value for sample.
So many need to use a nested composite key?
vlad
10
I have no idea what you are talking about.
Actually I have
public class EmbedddedSamplesKey implements Serializable {
private Integer id;
private int year;
...
}
Who are used in Samplings
In sample for its pk I would like to use pk of Sampling + letter (from sample)
vlad
12
Use @Id along with @ManyToOne. You should already know that from the User Guide chapter I mentioned earlier.