更新创建新的子对象,而不是更新现有的Hibernate

时间:2017-11-26 02:58:15

标签: java hibernate spring-boot mapping

在我的春季启动应用程序中,我有一个带有一个Exercise对象列表的Workout对象。问题是当我尝试更新Workout时,属于Workout的练习没有更新。相反,它在数据库中创建新的Exercise对象。我已经添加了我的锻炼实体和下面的锻炼实体。任何帮助将不胜感激。

锻炼课程:

@Entity
public class Workout {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;


@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "workout_id")
private List<Exercise> exercises;

public Workout(List<Exercise> exercises) {
    this.exercises = exercises;
}

public Workout() {
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public List<Exercise> getExercises() {
    return exercises;
}

public void setExercises(List<Exercise> exercises) {
    this.exercises = exercises;
}
}

练习课:

@Entity
@Table
public class Exercise {

@Id
@GeneratedValue
private Long id;


private String exerciseName;
private int weight;
private int actualReps;

@ManyToOne
@JoinColumn(name = "workout_id")
private Workout workout;

public Exercise(){}


public Exercise( String exerciseName, int weight, int actualReps) {
    this.exerciseName = exerciseName;
    this.weight = weight;
    this.actualReps = actualReps;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getExerciseName() {
    return exerciseName;
}

public void setExerciseName(String exerciseName) {
    this.exerciseName = exerciseName;
}

public int getWeight() {
    return weight;
}

public void setWeight(int weight) {
    this.weight = weight;
}

public int getActualReps() {
    return actualReps;
}

public void setActualReps(int actualReps) {
    this.actualReps = actualReps;
}
}

控制器:

@Controller
public class WorkoutController {

@Autowired
private WorkoutService workoutService;
@Autowired
private OneRepMaxService oneRepMaxService;
@Autowired
private ActualRepsService actualRepsService;
@Autowired
private PercentageService percentageService;
@Autowired
private ExerciseService exerciseService;



@RequestMapping("/")
@SuppressWarnings("unchecked")
public String showWorkout(Long id, Model model,Workout workout){





    Workout firstWorkout = workoutService.findById(Long.valueOf(83));

    model.addAttribute("firstWorkout",firstWorkout);
    model.addAttribute("workout",workout);

    return "workout";
}

@RequestMapping(value="/workoutLogs", method = RequestMethod.POST)
public String saveWorkout(@ModelAttribute Workout workout,Model model) {


    workoutService.saveNewWorkout(workout);


    return "redirect:/workoutLogs";
}


@RequestMapping("/workoutLogs")
public String showAllSavedWorkoutLogs(Model model){


    return "WorkoutLogs";

}



}

WorkoutDao:

@Repository
public class WorkoutDaoImpl implements WorkoutDao {

@Autowired
SessionFactory sessionFactory;

@Override
@SuppressWarnings("unchecked")
public List<Workout> findAll() {
    Session session = sessionFactory.openSession();
    List<Workout> workouts = session.createCriteria(Workout.class).list();
    session.close();
    return workouts;
}

@Override
public Workout getFirstWorkoutExerciseName(Long id) {
    return null;
}

@Override
public Workout getWorkout() {
    return null;


}


@Override
public Workout findById(Long id) {
    Session session = sessionFactory.openSession();
    Workout workout = session.get(Workout.class,id);
    Hibernate.initialize(Workout.class);
    return workout;
}


@Override
public void save(Workout workout) {
    Session session = sessionFactory.openSession();

    // Begin a transaction
    session.beginTransaction();

    // Save the category
    session.saveOrUpdate(workout);

    // Commit the transaction
    session.getTransaction().commit();

    // Close the session
    session.close();
}

@Override
public void delete(Workout workout) {

}


}

1 个答案:

答案 0 :(得分:0)

使用mappedBy进行双向关联,并且不要在关联的每一方使用@JoinColumnwhat is @JoinColumn and how it is used in Hibernate)。

@OneToMany(mappedBy = "workout", cascade = CascadeType.ALL)
private List<Exercise> exercises;

@ManyToOne
@JoinColumn(name = "workout_id")
private Workout workout;

如果您希望orphanRemoval = true行在不属于Exercise

时删除,请使用Workout
@OneToMany(mappedBy = "workout", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Exercise> exercises;

从数据库更新Workout

  1. 从数据库中获取Workout
  2. Exercise集合中更新一些exercises
  3. 更新/合并Workout
  4. 从数据库更新exercises

    您可以按Workout ID获取一系列练习(不Workout)。并更新其中任何一个,并saveOrUpdate每个。{/ p>

    从请求中更新Workout

    您应该在Workout中拥有ID。另外,现有Exercise的每个id都会更新(并且会在不存在id的情况下创建,至少对于Hibernate 4.11而言),每个Exercise都会创建无ID,每个exercises Exercise集合orphanRemoval = true中不存在的内容将被merge()删除。

    在这种情况下始终使用saveOrUpdate()@Override public Workout findById(Long id) { Session session = sessionFactory.openSession(); Workout workout = session.get(Workout.class,id); Hibernate.initialize(Workout.class); return workout; } 将无效(至少练习不会被删除)。

    这是一种不正确的方法:

    Hibernate.initialize(Workout.class)

    您需要关闭会话,这是垃圾 +----+------+ |key |value | +----+------+ | 1 | 500.0| | 2 | 250.0| | 3 | 350.0| | 1 | 250.0| | 2 | 150.0| +----+------+