| We updated from 5.3.6 to 5.4.0 when this issue showed itself. We've also used every major version before that since 2011 or so, with only very small changes to the data model (only added new entities). (The funny thing is: Our codebase seems to be a very good test base for Hibernate, because almost every release of Hibernate breaks something major for us (not saying that it is always Hibernates fault) The entities that broke with this change roughly looked like this (many properties omitted).
@Entity
public class Schedule {
private int id;
private ScheduleData data = new ScheduleData();
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
getData().setId(id);
}
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@BatchSize(size = 256)
public ScheduleData getData() {
return data;
}
public void setData(ScheduleData data) {
this.data = data;
}
}
@Entity
public class ScheduleData {
private int id;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
If you tell me that this is an invalid model, I will believe you immediately. This is one of the most exotic and most ancient parts of our data model. Hibernate doesn't create foreign key constraints for this model, so we added one manually:
Fortunately, I was able to properly fix this issue by changing the entities 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(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 Schedule id;
@Id
@OneToOne
@JoinColumn(foreignKey = @ForeignKey(name = "FK_ID"))
@OnDelete(action = OnDeleteAction.CASCADE)
public Schedule getId() {
return id;
}
public void setSchedule(Schedule id) {
this.id = id;
}
}
This seems to be possible since JPA 2.0, where you can use @Id and @OneToOne on the same attribute. This also creates the foreign key constraint for us, which is nice. I am not too sure if the model was invalid before (but it sure feels this way). If you still want a test case, I will see what I can do. Thanks for hearing me out! |