| I realize that the issue tracker is not a support forum, so I want to thank you for your help! Because this issue is highly visited and even linked from Stackoverflow, please let me show you how I've completely solved the issue for me. Maybe this will be useful for someone visiting later. @Gail Badner Your solution looks nice and will probably work, too. But after further investigating my own solution, I noticed that the lazy loading of Schedule.getData() didn't work - even when adding "optional = false" to the @OneToOne annotation. Don't get me wrong: Lazy loading most like also didn't work with my original (invalid) model. But the "FetchType.LAZY" part makes me believe that the original author wants this to work, so I investigated futher into it. Then I discovered this excellent blog post by the awesome Vlad Mihalcea: https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/ I am sure I've read this blog post several times in the past and modelled quite some entities after this, but forgot about it. Anyway, the blog post shows the very best solution for exactly my use case: A non-optional one-to-one relation with a shared primary key. Long story short, I've changed my entities to look like this:
@Entity
public class Schedule {
private int id;
private ScheduleData data = new ScheduleData();
public Schedule() {
data.setSchedule(this);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "schedule")
@BatchSize(size = 256)
public ScheduleData getData() {
return data;
}
public void setData(ScheduleData data) {
this.data = data;
}
}
@Entity
public class ScheduleData {
private int id;
private Schedule schedule;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OnDelete(action = OnDeleteAction.CASCADE)
@OneToOne(fetch = FetchType.LAZY, optional = false)
@MapsId
@JoinColumn(name = "id", foreignKey = @ForeignKey(name = "FK_ID"))
public Schedule getSchedule() {
return schedule;
}
public void setSchedule(Schedule schedule) {
this.schedule = schedule;
}
}
This doesn't change the the database schema, works exactly like before and even supports lazy loading. The only difference is the new public method ScheduleData.getSchedule(), but I am completely okay with that. In fact, I have used the exact same pattern in several other entities over the last few years, so it was high time to finally "fix" this ancient entity  |