2017-11-26 11 views
0

私の春のブートアプリケーションでは、Exerciseオブジェクトのリストを持つWorkoutオブジェクトがあります。問題は、ワークアウトを更新しようとしたときに、ワークアウトに属するエクササイズが更新されていないことです。代わりに、データベースに新しいExerciseオブジェクトを作成しています。ワークアウトエンティティとエクササイズエンティティを以下に追加しました。どんな助けでも大歓迎です。更新すると、既存のものを更新するのではなく、新しい子オブジェクトが作成されます。Hibernate

ワークアウトクラス:

@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

これらのDAOをSpring Dataを使用して自動生成するのではなく、特別な理由がありますか? – chrylis

+0

私は教えられただけの理由はありません。私は自分のプロジェクトに春のデータを追加しませんでした。私はSpring Bootを使用しています。 –

答えて

0

双方向アソシエーションにはmappedByを使用し、アソシエーションの各側には@JoinColumnを使用しないでください(what is @JoinColumn and how it is used in Hibernate)。これは、データベースからWorkout更新Workout

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

に属していないときは、Exercise行にしたい場合は

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

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

使用orphanRemoval = trueを削除する

  1. ゲットWorkoutデータベースから。
  2. Exerciseexercisesコレクションから更新します。
  3. 更新/あなたがWorkout idで(Workoutなし)演習のコレクションを取得することができますデータベース

    からのアップデートWorkout

exercisesをマージします。そしてそれらのいずれかを更新し、それぞれsaveOrUpdateを更新してください。あなたはWorkoutにIDを持っている必要があり、要求

からWorkoutの更新

。また、各Exerciseが存在するidは、id(少なくともHibernate 4.11の場合は存在しません)で更新されます。Exerciseのidは作成されません。exercisesコレクションに存在しないものは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)です。

関連する問題