Jak usunąć obiekt z repozytorium używając jego id. spring+thymeleaf

0

Zaczynam naukę springa.
Wyświetlam w /journeys listę moich journey, dodanych do bazy, w taki sposób:

<table>
        <tr th:each="trip : ${trips}">
            <td th:text="${trip.title}"></td>
            <td th:text="${trip.destination}"></td>
            <td th:text="${trip.id}"></td>
        </tr>
    </table>

W nowej komórce chciałbym button-delete przy każdym wylistowanym obiekcie, żeby po kliknięciu, żądany obiekt usuwać i odświeżać stronę. Wyczytałem na internetach, że muszę zrobić to przy pomocy formularza, polem typu hidden, więc popełniłem coś takiego:

 `<table>
        <tr th:each="trip : ${trips}">
            <td th:text="${trip.title}"></td>
            <td th:text="${trip.destination}"></td>
            <td th:text="${trip.id}"></td>
                <form th:action="@{/journeys}" th:object="${trip}" method="post">
                    <input type="hidden" th:field="${id}" />
                    <button type="submit">Delete</button>
                </form>
        </tr>
    </table>

Mój kontroler wygląda następująco:

 @RequestMapping(value = {"/journeys"}, method = RequestMethod.GET)
    public String journeysPage(Model model){
        return "journeysSite";
    }

 @RequestMapping(value = {"/journeys"}, method = RequestMethod.POST)
    public String journeysPageTripDeleting(@ModelAttribute Trip trip){
        tripRepository.delete(trip.getId());

        return "redirect:/journeys";
    }

Oczywiście coś schrzaniłem i przy próbie wejścia na /journeys dostaję:

 java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'id' available as request attribute

Mógłby ktoś zarzucić jakąś poradą gdzie popełniłem błąd?

1

W GetRequescie nie przekazałeś do widoku żadnego obiektu.
Przykład

 @RequestMapping(value = {"/journeys"}, method = RequestMethod.GET)
    public ModelAndView journeysPage(){
        ModelAndView mav = new ModelAndView("journeysSite");
        mav.addObject("nazwa", obiekt1);
        return mav;
    }
 <form th:action="@{/journeys}" th:object="${trip}" method="post">
                    <input type="hidden" th:field="${id}" />
                    <button type="submit">Delete</button>
  </form>

W tym fragmencie przypisujesz do obiektu przekazanego do widoku pod nazwą "trip" wartości ale w wyżej wspominanym requeście nie przekazujesz obiektu do którego te dane mogłyby być zbindowane i przesłane postem.

W twoim przypadku skoro chcesz operować na liście "trips" czyli powinieneś ja do widoku w tej formie przekazac oraz obiekt odpowiedzialny za zbindowanie wartości formularza czyli jakiś trip, który przekazywałby dane z <form> do żądania post

Co do obsługi to właśnie to robią

        th:object="${trip}"      <--- odwołanie do obiektu przekazanego w requeście   mav("trip", new Trip())
        th:field="*{id}"           <--- zbindowanie wartości inputa do pola obiektu trip
 <form th:action="@{/journeys}" th:object="${tripForm}" method="post">
                    <input type="hidden" th:value="${trip.id}" name="id"/>
                    <button type="submit">Delete</button>
  </form>
'''

I w Poscie odbierasz @ModelAttribute("tripForm")
0

Dzięki poradom @okcam doszedłem do czegoś takiego:

Controller

 @RequestMapping(value = {"/journeys"}, method = RequestMethod.GET)
    public ModelAndView journeysPage(Model model){
        ModelAndView mav = new ModelAndView("journeysSite");
        mav.addObject("tripForm", new Trip("sample", "sample"));  //mój Trip() jest protected, nie wiem czy lepiej zmienić to na public, czy przekazywać tutaj jakieś randomowe argumenty.
        mav.addObject("trips", tripRepository.findAll());
        return mav;
    }

    @RequestMapping(value = {"/journeys"}, method = RequestMethod.POST)
    public String journeysPageTripDeleting(@ModelAttribute("tripForm") Trip trip){
        tripRepository.delete(trip.getId());

        return "redirect:/journeys";
    }

oraz widok /journeys

 <table>
        <tr th:each="trip : ${trips}">
            <td th:text="${trip.title}"></td>
            <td th:text="${trip.destination}"></td>
            <td th:text="${trip.id}"></td>
                <td><form th:action="@{/journeys}" th:object="${tripForm}" method="post">
                    <input type="hidden" th:field="*{id}" th:value="${trip.id}" />
                    <button type="submit">Delete</button>
                </form></td>
        </tr>
    </table>

Teraz to co się wyprawia to

 java.lang.IllegalArgumentException: The given id must not be null!

i w sumie nie mam pomysłu co dalej ;/

Uptade:

<input type="hidden" th:value="${trip.id}" name="id" />

działa idealnie!

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