保存带有外键的对象不返回数据库中的ID



我有一个电影预订系统,用户可以在其中添加电影,然后他们可以为每部电影添加日期。它工作得很好,但是当用户添加日期时,没有错误,但是它以movie_id = null保存到数据库。

我怎么解决它?

Movie.java

@Data
@Entity
public class Movie {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private Long id;
@Column(unique = true)
private String title;

private String category;
@Column( columnDefinition = "TEXT")
private String description;
private Integer lenght;
private Integer minAge;
@Column(columnDefinition = "TEXT")
private String imageUrl;
@OneToMany(mappedBy = "movie", orphanRemoval = true)
private List<Repertoire> repertoires;
public Movie() {
}
}

Repertoire.java

@Data
@Entity
public class Repertoire {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private Long id;
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime date;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "movie_id")
private Movie movie;
}

MovieController.java

@Controller
@RequestMapping("/movies")
public class MovieController {
private MovieRepo movieRepo;
private RepertoireRepo repertoireRepo;
@Autowired
public MovieController(MovieRepo movieRepo, RepertoireRepo repertoireRepo) {
this.movieRepo = movieRepo;
this.repertoireRepo = repertoireRepo;
}
@GetMapping("showForm")
public String showStudentForm(Movie movie) {
return "add-movie";
}
@GetMapping("list")
public String getMovies(Model model) {
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}
@PostMapping("add")
public String movies(@Validated Movie movie, BindingResult result, Model model) {
if(result.hasErrors()) {
return "add-movie";
}
movieRepo.save(movie);
return "redirect:/movies/list";
}
@GetMapping("edit/{id}")
public String showUpdateForm(@PathVariable ("id") long id, Model model) {
Movie movie = movieRepo.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Nieprawidłowe ID: " + id));
model.addAttribute("movie", movie);
return "update-movie";
}
@PostMapping("update/{id}")
public String updateMovie(@PathVariable("id") long id, @Validated Movie movie, BindingResult result, Model model) {
if(result.hasErrors()) {
movie.setId(id);
return "update-movie";
}
movieRepo.save(movie);
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}
@GetMapping("delete/{id}")
public String deleteMovie(@PathVariable ("id") long id, Model model) {
List<Repertoire> repertoires = repertoireRepo.findByMovieId(id);
repertoires.forEach(r -> repertoireRepo.deleteById(r.getId()));
Movie movie = movieRepo.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Nieprawidłowe ID : " + id));
movieRepo.delete(movie);
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}

// HERE'S WHERE I ADD THE TIME:
@GetMapping("/admin/{movieName}/newRepertoire")
public String showRepertoireForm(Model model, @PathVariable ("movieName") String movieName) {
Movie movieRepertoire = movieRepo.findByTitle(movieName);
model.addAttribute("movieRepertoire", movieRepertoire);
model.addAttribute("repertoire", new Repertoire());
return "repertoire";
}
@PostMapping("/admin/newRepertoire")
@Transactional
public String addRepertoire(@ModelAttribute ("repertoire") Repertoire repertoire,
@ModelAttribute("movieRepertoire") Movie movie, BindingResult result) {
//        if(result.hasErrors()) {
//            return "repertoire";
//        }

repertoire.setMovie(movieRepo.findByTitle(movie.getTitle()));
repertoireRepo.save(repertoire);
return "redirect:/movies/list";
}
}

RepertoireRepo.java

@Repository
public interface RepertoireRepo extends JpaRepository<Repertoire, Long> {
List<Repertoire> findByMovieId(Long movieId);
}

MovieRepo.java

@Repository
public interface MovieRepo extends JpaRepository<Movie, Long> {
Movie findByTitle(String title);
}

repertoire.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>c</title>
</head>
<body>
<div class="container my-5">
<div class="card">
<div class="card-body">
<div class="col-md-10">
<h1 th:text="${movieRepertoire.title}"> MovieName</h1>
<form action="#" th:action="@{/movies/admin/newRepertoire}" th:object="${repertoire}" method="post">
<div class="row">
<div class="form-group col-md-8">
<label for="date" class="col-form-label">Date</label>
<input type="datetime-local" th:field="*{date}" class="form-control" id="date" value="2021-01-20T13:01">
<span th:if="${#fields.hasErrors('date')}" th:errors="*{date}" class="text-danger"></span>
</div>
<div class="col-md-6">
<input type="submit" class="btn btn-primary" value="Add">
</div>
<div class="form-group col-md-8"></div>
</div>
<!--                    <input type = "hidden" th:value="${movieRepertoire}">-->
</form>
</div>
</div>
</div>
</div>
</body>
</html>

电影结构:

id | category | description | imageurl| lenght| minage| title
------------------------- 
36 | Action | Simple desc. | photo.jpg | 137 | 7 | Iron Man |

曲目结构:

id | date | movie_id
------------------------- 
37 | 2021-01-01 14:00:00 | null |

关系的双方都必须更新,您应该从父级保存。代码:

repertoire.setMovie(movieRepo.findByTitle(movie.getTitle()));
repertoireRepo.save(repertoire);

应该成为:

Movie movie = movieRepo.findByTitle(movie.getTitle());
movie.getRepertoires().add(repertoire);
repertoire.setMovie(movie);
session.saveOrUpdate(movie);

事实上,你应该在Movie中添加一个辅助方法来执行这两个操作,以确保关系的双方始终保持同步:

public void addRepertoire(Repertoire repertoire) {
repertoires.add(repertoire);
repertoire.setMovie(this);
}

最新更新