java - 使用休眠的子(外键)对象的父(主键)永远不会被设置
问题描述
在操作过程中,父 PK 没有被设置为子的 FK INSERT
。
这是错误:
org.postgresql.util.PSQLException:错误:“workout_id”列中的空值违反非空约束
详细信息:失败行包含 (20ea52e3-0491-480f-b3c1-b1da70feee8f, null, null, 510, 55, KG, Olympic)。
在这种情况下,只会生成一个 ID,即为孩子。永远不会创建父 ID,因此 FK 约束被破坏并且 DB 事务失败。
为了解决这个问题,我从父级中删除了子级,并且UUID
确实为父级生成了一个。
在下面的示例中,Workout
是父级,并且Set
是子级。还显示了执行持久性操作的端点。
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "workouts")
public class Workout implements Serializable {
@Id
@Type(type = "pg-uuid")
@GeneratedValue(generator="UUID")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private UUID id;
@Column(name="user_id")
private long user; // todo use UUID
@Column(name="name")
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "workout")
//@JoinColumn(columnDefinition="uuid", name = "workout_id")
private List<Set> set;
@Column(name="start_time")
private String startTime;
@Column(name="stop_time")
private String stopTime;
@Column(name="notes")
private String notes;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "exercise_sets")
public class Set {
@Id
@Type(type = "pg-uuid")
@GeneratedValue(generator="UUID")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private UUID id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="workout_id")
private Workout workout;
@Column(name="reps")
private Integer numberOfReps;
@Column(name="weight")
private Integer weightLifted;
@Column(name="unit")
private String weightUnit;
@Column(name="bar_type")
private String barType;
}
@RequestMapping(value="/user/{id}", method=RequestMethod.POST)
public ResponseEntity<Object> addWorkoutForUser(@PathVariable(name="id") long id) {
Set s = Set.builder()
//.workout(w)
//.workoutId(1)
.numberOfReps(10)
.weightLifted(25)
.weightUnit("KG")
.barType("Olympic").build();
Set s2 = Set.builder()
//.workout(w)
//.workoutId(1)
.numberOfReps(510)
.weightLifted(55)
.weightUnit("KG")
.barType("Olympic").build();
Workout w = Workout.builder()
.set(Arrays.asList(s2,s))
.name("My First Workout")
.notes("Felt great")
.startTime("now")
.stopTime("later").build();
Workout persistedData = this.workoutDao.save(w);
return ResponseEntity.ok(persistedData);
}