I have strange database structure where I have a pair of 2 foreign keys as primary key in 1 table. In another table I have 3 foreign keys and as a primary key and I struggle to make that as a JPA entity class. The error I get is: Cannot change column 'workstep_no': used in a foreign key constraint 'fk_order_has_workstep_workstep'
Here is the db Schema:
Here are some of my entity classes
OrderHasWorkstep
@Entity
@Table(name = "order_has_workstep", indexes = {
@Index(name = "fk_order_has_workstep_order_idx", columnList = "order_order_no"),
@Index(name = "fk_order_has_workstep_workstep_idx", columnList = "workstep_workstep_no, workstep_article_article_no"),
@Index(name = "fk_order_has_workstep_machine_idx", columnList = "machine_machine_no")
})
public class OrderHasWorkstep {
@EmbeddedId
private OrderHasWorkstepId id;
@MapsId("orderOrderNo")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "order_order_no", nullable = false)
private Order orderOrderNo;
@MapsId("id")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumns({
@JoinColumn(name = "workstep_workstep_no", referencedColumnName = "workstep_no", nullable = false),
@JoinColumn(name = "workstep_article_article_no", referencedColumnName = "article_article_no", nullable = false)
})
@OnDelete(action = OnDeleteAction.CASCADE)
private Workstep workstep;
@ManyToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "machine_machine_no")
private Machine machineMachineNo;
@Column(name = "planned_calendar_week", length = 7)
private String plannedCalendarWeek;
@Column(name = "starting_date", length = 7)
private String startingDate;
@Column(name = "ending_date", length = 7)
private String endingDate;
@Column(name = "status")
private Integer status;
// getters and setters
OrderHasWorkstepId:
@Embeddable
public class OrderHasWorkstepId implements Serializable {
private static final long serialVersionUID = -488175951625341581L;
@Column(name = "order_order_no", nullable = false, length = 10)
private String orderOrderNo;
@Column(name = "workstep_workstep_no", nullable = false, length = 3)
private String workstepWorkstepNo;
@Column(name = "workstep_article_article_no", nullable = false, length = 45)
private String workstepArticleArticleNo;
//getters setters hashcode equals
Workstep:
@Entity
@Table(name = "workstep", indexes = {
@Index(name = "fk_workstep_article_idx", columnList = "article_article_no")
})
public class Workstep {
@EmbeddedId
private WorkstepId id;
@MapsId("articleArticleNo")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "article_article_no", nullable = false)
private Article articleArticleNo;
@Lob
@Column(name = "description")
private String description;
@Column(name = "setup_time")
private LocalTime setupTime;
@Column(name = "run_time")
private LocalTime runTime;
@Column(name = "machine_group", length = 5)
private String machineGroup;
//getters setters
WorkstepId
@Embeddable
public class WorkstepId implements Serializable {
private static final long serialVersionUID = 2987311413950947398L;
@Column(name = "workstep_no", nullable = false, length = 3)
private String workstepNo;
@Column(name = "article_article_no", nullable = false, length = 45)
private String articleArticleNo;
I tried to restructure the WorkstepIds to use entities not just strings but it still didnt work. I assume it could be something to do with the pair of columns as primary key taken into order_has_workstep
Try more simply:
@Entity
@Table(name = "order_has_workstep", indexes = {
@Index(name = "fk_order_has_workstep_order_idx", columnList = "order_order_no"),
@Index(name = "fk_order_has_workstep_workstep_idx", columnList = "workstep_workstep_no, workstep_article_article_no"),
@Index(name = "fk_order_has_workstep_machine_idx", columnList = "machine_machine_no")
})
@IdClass(OrderHasWorkstepId.class)
public class OrderHasWorkstep {
@Id
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "order_order_no", nullable = false)
private Order orderOrderNo;
@Id
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumns({
@JoinColumn(name = "workstep_workstep_no", referencedColumnName = "workstep_no", nullable = false),
@JoinColumn(name = "workstep_article_article_no", referencedColumnName = "article_article_no", nullable = false)
})
@OnDelete(action = OnDeleteAction.CASCADE)
private Workstep workstep;
..
}
public class OrderHasWorkstepId implements Serializable {
private static final long serialVersionUID = -488175951625341581L;
private String orderOrderNo;
private WorkstepId workstep;
..
}
With JPA derived IDs, the referenced entity's ID must be used as is in the ID class, and named the same as the ID property.