Объединение двух таблиц в Hibernate JPA - PullRequest
1 голос
/ 08 марта 2020

Я знаю, что этот вопрос задавался раньше, я просто борюсь с ним с помощью своего кода.

У меня есть две таблицы: таблица фильмов и таблица user_movies. Я хочу присоединиться к ним, у фильмов есть PK movie_id, а у user_movies есть FK с тем же именем.

Я создал свои репозитории, и они отлично работают, как мои сохранения в моих соответствующих контроллерах, так же, как и мои basi c findby запросов

Однако мой findAll в моем MoviesController (метод movie) не работает, он дает мне неправильное имя таблицы и столбца. Вот мой код.

Трассировка стека дает мне эту ошибку

java. sql .SQLSyntaxErrorException: неизвестный столбец 'usermovies0_.movies_movie_id' в 'списке полей'

Что я не могу понять, так это то, что я делаю неправильно, что он генерирует это имя таблицы и имя столбца, а не использует те, которые у меня есть ??

UserMovies. 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);
    }


}

1 Ответ

2 голосов
/ 09 марта 2020

Вы не предоставляете имя объединяющего столбца для следующей @ManyToOne ассоциации:

@ManyToOne(fetch = FetchType.LAZY)
private Movies movies;

Итак, hibernate пытается идентифицировать его, используя стратегию именования по умолчанию . В соответствии со спецификацией JPA (см. 2.10.3.2 однонаправленные отношения ManyToOne раздел):

Имя столбца внешнего ключа формируется как объединение следующего: имя отношения свойство или поле сущности 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;

    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...