首页 > 解决方案 > 使用休眠的子(外键)对象的父(主键)永远不会被设置

问题描述

在操作过程中,父 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);
    }

标签: javaspringpostgresqlhibernatejpa

解决方案


推荐阅读