Aktualizacja filmu powoduje duplikacje filmu

1

cześć,

od razy uprzedzam, że jestem totalnie zielony w kodzenie w Javie. obecnie próbuję stworzyć RESTowe API z wykorzystaniem Spring Boota.

po próbie zaktualizowania danych z wykorzystaniem PUTa tablica się aktualizuje, tylko po ponownym pobraniu danych danych GETem pokazuje się ona dwa razy (oczywiście z innym id). z czego to może wynikać? gdzie popełniłem błąd? czy istnieje jakaś prostsza metoda zapisania updateMovie()?

będę wdzięczny za każdą formę pomocy :D

MovieController:

@PutMapping(path = "{id}")
public void updateMovie(@RequestBody Movie movie, @PathVariable Long id){
    Movie updateMovie = movieRepository.findById(id).orElseThrow(() -> new IllegalStateException("A title with such id:" + id + "does not exist."));

    updateMovie.setType_movie(movie.getType_movie());
    updateMovie.setTitle(movie.getTitle());
    updateMovie.setRelease_year(movie.getRelease_year());
    updateMovie.setGenre(movie.getGenre());
    updateMovie.setDirector(movie.getDirector());
    updateMovie.setImdb_rating(movie.getImdb_rating());
    updateMovie.setStoryline(movie.getStoryline());

    movieService.updateMovie(movie, id);
}

MovieService:

public void updateMovie(Movie movie, Long id) {
    Optional<Movie> movieOptional = movieRepository
            .findMovieByTitle(movie.getTitle());
    if (movieOptional.isPresent()){
        throw new IllegalStateException("This title is already in the database.");
    }
    movieRepository.save(movie);
}

GET:
screenshot-20221230141436.png

PUT:
screenshot-20221230141520.png

GET2:
screenshot-20221230141544.png

3

W jakim celu w movieService.updateMovie(movie, id); dałeś zarówno movie, jak i id? Przecież to nie ma żadnego sensu. Tak samo z po co ta ścieżka path = "{id}"? Wtedy podczas aktualizowania danych będziesz musiał podawać id w URL. Jaki jest tego cel? Nie wiem.
Po co dodałeś następujące Exception: "A title with such id:" + id + "does not exist." . To jest w ogóle nieużyteczne, przecież gdy ktoś będzie chciał zaktualizować jakieś dane dotyczące filmu, to wyrzuci mu błąd i przez to nie zaktualizuje np. oceny na IMDB albo opisu. Totalny bez sens.

2

Do metody updateMovie powinieneś przekazać obiekt updateMovie, a nie movie, movie jest z frontu i Hibernate czy co tam jest pod spodem nie śledzi tego obiektu i save dodaje go do bazy :D
PS Korzystasz bardzo źle z Optionala.

0

Zgadzam się z przedmówcami jednak IMHO dzieją się tu rzeczy niestworzone.
Mimo wszystko kod:

     Optional<Movie> movieOptional = movieRepository
                .findMovieByTitle(movie.getTitle());
        if (movieOptional.isPresent()){
            throw new IllegalStateException("This title is already in the database.");
        }

powinien rucić exception, a nie rzuca co znaczy że .findMovieByTitle(movie.getTitle()); nie znajduje. findMovieByTitle jest z generatora czy sam pisałeś? Pokaż ciało tej metody

BTW kod

        updateMovie.setType_movie(movie.getType_movie());
        updateMovie.setTitle(movie.getTitle());
        updateMovie.setRelease_year(movie.getRelease_year());
        updateMovie.setGenre(movie.getGenre());
        updateMovie.setDirector(movie.getDirector());
        updateMovie.setImdb_rating(movie.getImdb_rating());
        updateMovie.setStoryline(movie.getStoryline());

IMHO nie robi nić, bo zmiennej updateMovie nie używasz

1

A to movieRepository to co to jest? to jest repo JPA czy jakieś Twoje? Jak Twoje, to pokaż kod.

0
Riddle napisał(a):

A to movieRepository to co to jest? to jest repo JPA czy jakieś Twoje? Jak Twoje, to pokaż kod.

@Riddle: tak, movieRepository sam tworzyłem, na podstawie filmu

@Repository
public interface MovieRepository extends JpaRepository<Movie, Long> {

    @Query("select m from Movie m where m.title=?1")
    Optional<Movie> findMovieByTitle(String title);
}
1
jacek.nowakiewicz napisał(a):
Riddle napisał(a):

A to movieRepository to co to jest? to jest repo JPA czy jakieś Twoje? Jak Twoje, to pokaż kod.

@Riddle: tak, movieRepository sam tworzyłem, na podstawie filmu

@Repository
public interface MovieRepository extends JpaRepository<Movie, Long> {

    @Query("select m from Movie m where m.title=?1")
    Optional<Movie> findMovieByTitle(String title);
}

No to właśnie nie sam stworzyłeś, tylko użyłeś JPA :D

0

aha. dobrze wiedzieć :D no tak jak pisałem, dopiero zaczynam przygodę z Javą, ale cały czas mnie ktoś uświadamia ile jeszcze pracy przede mną

0

@Riddle: mógłbyś mi jakoś pomóc? albo chociaż jakoś mnie naprowadzić na proces poprawnego myślenia? :P

2

mógłbym cię prosić o jakieś bardziej szczegółowe naprowadzenie? bo nie bardzo wiem, które fragmenty, w jaki sposób mogę zmienić :/ —

A chodzi o pierwszy kody czy o drugi?
Bo jak o drugi po BTW to ten kod jest totalnie bez sensu.
Co do pierwszego to nie wiem:

  • zobaczenie w logach co tam się dzieje - jaki parametr został przekazany do funkcji
  • sprawdzenie w debugerze co tam jest przekazywane do findMovieByTitle. No kodu samego findMovieByTitle nie zdebugjesz bo jest magiczny
jacek.nowakiewicz napisał(a):

@KamilAdam: przesyłam ciało metody:

@Repository
public interface MovieRepository extends JpaRepository<Movie, Long> {

    @Query("select m from Movie m where m.title=?1")
    Optional<Movie> findMovieByTitle(String title);
}

No właśnie ciała metody tu nie ma bo jest magia przez JPA robiona. A magii nie zdebugujesz. Możesz tylko próbowac użuwać logowania i sprawdzać co tam w logu jest

0

Robisz save na obiekcie który nie ma ustawionego ID, a jak nie ma ID to JPA zrobi insert, a nie update.

Żeby zrozumieć problem ustaw ID przed zapisem:

movie.setId(id)
movieRepository.save(movie);

Jak już zrozumiesz w czym problem, to skorzystaj z rad przedmówców, bo to co przedstawiłem ma tylko pokazać dlaczego leci update, a nie insert.
Spróbuj zrozumieć w czym są problemy, a następnie najlepiej wykasuj cały kod i napisz od nowa :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1