hibernate - 在 Hibernate JPA 中连接两个表
问题描述
我知道以前有人问过这个问题,我只是在用我的代码来解决这个问题。
我有两个表,一个电影表和一个 user_movies 表。我想加入他们,电影有一个movie_id 的PK,而user_movies 有一个同名的FK。
我创建了我的存储库,它们工作正常,因为我在各自控制器中的保存工作正常,我的基本 findby 查询也是如此
但是,我的 MoviesController (电影方法)中的 findAll 不起作用,它给了我错误的表和列名。这是我的代码。
堆栈跟踪给了我这个错误
java.sql.SQLSyntaxErrorException:“字段列表”中的未知列“usermovies0_.movies_movie_id”
我无法弄清楚我做错了什么,它正在生成表名和列名,而不是使用我拥有的那些?
用户电影.java
package movieweb.movies.models;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name="user_movies")
public class UserMovies implements Serializable {
private static final long serialVersionUID = 2L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_movie_id")
private Integer userMovieID;
@Column(name = "movie_id")
private Integer movieId;
@Column(name = "uname")
private String uname;
@ManyToOne(fetch = FetchType.LAZY)
private Movies movies;
public UserMovies() {
}
public UserMovies(Integer userMovieID, Integer movieId, String uname) {
super();
this.userMovieID = userMovieID;
this.movieId = movieId;
this.uname = uname;
}
public Integer getUserMovieID() {
return userMovieID;
}
public void setUserMovieID(Integer userMovieID) {
this.userMovieID = userMovieID;
}
public Integer getMovieId() {
return movieId;
}
public void setMovieId(Integer movieId) {
this.movieId = movieId;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
电影.java
package movieweb.movies.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name="movies")
public class Movies implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "movie_id")
private Integer movieId;
@Column(name= "movie_name")
private String movieName;
@Column(name="movie_description")
private String movieDescription;
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, mappedBy = "movies")
private List<UserMovies> userMovies;
public Movies() {
}
public Movies(Integer movieId, String movieName, String movieDescription) {
super();
this.movieId = movieId;
this.movieName = movieName;
this.movieDescription = movieDescription;
}
public Integer getMovieId() {
return movieId;
}
public void setMovieId(Integer id) {
this.movieId = id;
}
public String getMovieName() {
return movieName;
}
public void setMovieName(String name) {
this.movieName = name;
}
public String getMovieDescription() {
return movieDescription;
}
public void setMovieDescription(String description) {
this.movieDescription = description;
}
public List<UserMovies> getUserMovies() {
return userMovies;
}
public void setUserMovies(List<UserMovies> userMovies) {
this.userMovies = userMovies;
}
}
UserMoviesController.java
package movieweb.movies.controllers;
import movieweb.movies.models.UserMovies;
import movieweb.movies.repository.UserMoviesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class UserMoviesController {
@Autowired
private UserMoviesRepository umRepository;
@CrossOrigin
@PostMapping(path = "/newUserMovie")
public UserMovies addNewUserMovie(@RequestBody UserMovies data){
return umRepository.save(data);
}
@CrossOrigin
@GetMapping(path="/getUserMovies")
public @ResponseBody List<UserMovies> getUserMovies(){
return (List<UserMovies>) umRepository.findAll();
}
}
MoviesController.java
package movieweb.movies.controllers;
import movieweb.movies.models.Movies;
import movieweb.movies.models.UserMovies;
import movieweb.movies.models.Users;
import movieweb.movies.repository.MoviesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;
@RestController
public class MoviesController {
@Autowired
private MoviesRepository moviesRepository;
@Autowired
private RestTemplate restTemplate;
@CrossOrigin
@GetMapping(path = "/movies")
public @ResponseBody List<Movies> movies(){
List<Movies> allMovies = (List<Movies>) moviesRepository.findAll();
if (!allMovies.isEmpty()){
return allMovies;
} else {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Movies not found"
);
}
}
// @CrossOrigin
// @RequestMapping(path = "movies/user/{id}")
// public List<Movies> movie(@PathVariable("id") int id){
// return this.movies().stream().map(movie -> {
// Users[] user = restTemplate.getForObject("http://127.0.0.1:8082/users/" + id, Users[].class);
// return new Movies(movie.getMovieId(), movie.getMovieName(), "Description");
// })
// .collect(Collectors.toList());
// }
@CrossOrigin
@GetMapping(path="/movie/{id}")
public @ResponseBody Movies getMovie(@PathVariable Integer id){
return moviesRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.NOT_FOUND, "Movie not found"
) );
}
@CrossOrigin
@DeleteMapping("/movie/delete/{id}")
void deleteMovie(@PathVariable Integer id) {
moviesRepository.deleteById(id);
}
@CrossOrigin
@PutMapping("/movie/update/{id}")
Movies updateMovie(@RequestBody Movies updateMovie, @PathVariable Integer id) {
return moviesRepository.findById(id)
.map(Movies -> {
Movies.setMovieName(updateMovie.getMovieName());
Movies.setMovieDescription(updateMovie.getMovieDescription());
return moviesRepository.save(Movies);
})
.orElseGet(() -> {
updateMovie.setMovieId(id);
return moviesRepository.save(updateMovie);
});
}
@CrossOrigin
@PostMapping(path="/newMovie")
public Movies addNewMovie (@RequestBody Movies data) {
return moviesRepository.save(data);
}
}
解决方案
您没有为以下@ManyToOne
关联提供连接列名称:
@ManyToOne(fetch = FetchType.LAZY)
private Movies movies;
因此,hibernate 尝试使用默认命名策略来识别它。根据 JPA 规范(参见2.10.3.2 单向多对一关系部分):
外键列名由以下内容串联构成:实体的关系属性或字段的名称
A
;"_"; 表中主键列的名称B
。外键列与表的主键类型相同B
。
因此,此关联的连接列名称将是movies_movie_id
. 但它在表中不存在,user_movies
因此您会在问题异常中得到提及。
您应该UserMovies
通过以下方式更正实体的映射:
@Entity
@Table(name="user_movies")
public class UserMovies implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_movie_id")
private Integer userMovieID;
@Column(name = "uname")
private String uname;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "movie_id")
private Movies movies;
// ...
}
推荐阅读
- ms-access - 如何使用公共子引用子窗体中的控件
- angular - 当广告在我的文件中添加代码时,我收到错误“./src/app/app.module.ts Module not found: Error: Can't resolve '@angular/http'”
- python - 如何修复将数据写入 pgm 文件的错误
- javascript - 从 Hooks 重构为类组件
- python - 一行代码正在执行且没有错误但没有返回任何输出
- javascript - 触发 if 语句时如何更新对象键/值?
- go - http.Handler 在 golang 中没有被调用
- python - tkinter 按需添加标签
- c# - SQL Server - 将数据类型 float 转换为 bigint 时出错
- ssh - 如何使用 ssh 和 Serveo.Net 访问公共 Internet 上的 Jupyter Notebook?