在我的春季启动应用程序中,我有一个带有一个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) {
}
}
答案 0 :(得分:0)
使用mappedBy
进行双向关联,并且不要在关联的每一方使用@JoinColumn
(what 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
Workout
。Exercise
集合中更新一些exercises
。Workout
从数据库更新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|
+----+------+
。