Search code examples
springspring-bootspring-mvcspring-data-jpathymeleaf

Cannot DELETE data: There was an unexpected error (type=Not Found, status=404)


i'm new here tried the possible duplicates solutions however couldn't solve it. i'm trying to build a pretty simple hospital management system. i can create patient data, however when i click delete it to red button, it gives me this error.

view database

the patient controller:

package com.laboratory.app.controller;
import com.laboratory.app.entity.Patient;
import com.laboratory.app.service.PatientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@RestController
public class PatientController {

    // Patient service object
    @Autowired
    private PatientService patientService;


    @GetMapping(value="/register_patient")
    public ModelAndView registerPatient(Model model) {
        ModelAndView registerView = new ModelAndView("registerPatient/registerPatient");
        Patient newPatient = new Patient();
        model.addAttribute("patient", newPatient);
        return registerView;
    }

    @PostMapping(value="/save")
    public ModelAndView savePatient(@ModelAttribute("patient") Patient newPatient) {
        ModelAndView view = new ModelAndView("registerPatient/registeredSuccessfully");
        patientService.savePatient(newPatient);
        return view;
    }

    @DeleteMapping(value="/delete")
    public ModelAndView deletePatient(@RequestParam("patientId") String id) {
        ModelAndView view = new ModelAndView("home");
        patientService.deletePatient(Long.valueOf(id));
        return view;
    }

    @GetMapping(value="/view_database")
    public ModelAndView viewDatabase(Model model) {
        List<Patient> theEmployees = patientService.listAllPatients();
        model.addAttribute("patients", theEmployees);
        ModelAndView view = new ModelAndView("viewDatabase");
        return view;
    }

}

patient repository:

package com.laboratory.app.repository;
import com.laboratory.app.entity.Patient;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface PatientRepository extends JpaRepository<Patient, Long> {

    List<Patient> findAll(); // lists all the patients

    List<Patient> findAllByOrderByDateAddedAsc(); // show data by newest to oldest

    List<Patient> findAllByOrderByDateAddedDesc(); // show data by oldest to newest

    void deleteById(Long id);

    long count(); // return how many patients are there

    Optional<Patient> findById(Long id); // return the @Entity by id

    Patient save(Patient patient); // saves the patient into the database

    // show related data regarding searched name (case)
    List<Patient> findAllByPatientNameContainingIgnoreCase(String name);
    List<Patient> findAllByPatientSurnameContainingIgnoreCase(String name);

}

and patient service:

package com.laboratory.app.service;
import com.laboratory.app.entity.Patient;
import com.laboratory.app.repository.PatientRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

@Service
public class PatientService {
    @Autowired
    PatientRepository patientRepository;

    public List<Patient> listAllPatients() {
        return patientRepository.findAll();
    }

    public Patient savePatient(Patient patient) {
        return  patientRepository.save(patient);
    }

    public void deletePatient(Long id) {
        patientRepository.deleteById(id);
    }

    public long getPatientNum() {
        return patientRepository.count();
    }

    public Optional<Patient> findPatientById(Long id) {
        return patientRepository.findById(id);
    }

    public List<Patient> findPatientByName(String name) {
        return patientRepository.findAllByPatientNameContainingIgnoreCase(name);
    }

    public List<Patient> findPatientBySurname(String surname) {
        return patientRepository.findAllByPatientSurnameContainingIgnoreCase(surname);
    }

    public List<Patient> getAllPatientsSortedByDateAdded(boolean ascending) {
        if (ascending) {
            return patientRepository.findAllByOrderByDateAddedAsc();
        } else {
            return patientRepository.findAllByOrderByDateAddedDesc();
        }
    }
}

this is the html page:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <link rel="stylesheet" href="/style/viewDatabase.css">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <meta charset="UTF-8">
    <title>Patient Database</title>
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand text-white mr-3" href="/">Home</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    <li class="nav-item">
                        <a class="nav-link active text-white" aria-current="page" href="/home#about-id">About</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-white" href="view_database">Database</a>
                    </li>
                </ul>
                <div>
                    <a class="nav-link text-white" href="register_patient">Register Data</a>
                </div>
                <div>
                    <a class="nav-link text-white" href="log_in">Log In</a>
                </div>
                <div>
                    <a class="nav-link text-white" href="sign_up">Sign Up</a>
                </div>
            </div>
        </div>
    </nav>
    <div class="container">
        <h3 class="mt-4">This is the database page</h3>
        <p class="mb-3">You can see the table below.</p>
        <table class="table table-striped table-hover">
            <thead>
            <tr>
                <th scope="col">ID</th>
                <th scope="col">First</th>
                <th scope="col">Last</th>
                <th scope="col">Diagnosis</th>
                <th scope="col">For More</th>
            </tr>
            </thead>
            <tbody>
            <tr th:each="patient : ${patients}">
                <td th:text="${patient.patientId}"></td>
                <td th:text="${patient.patientName}"></td>
                <td th:text="${patient.patientSurname}"></td>
                <td th:text="${patient.patientDisease}"></td>
                <td>
                    <div class="show-more">
                        <strong><a href="#">Show</a></strong>
                    </div>
                </td>
                <td>
                    <a th:href="@{/patients/delete(patientId=${patient.getPatientId()})}"
                       onclick="if (!(confirm('Are you sure you want to delete this patient? ' +
                        'You can\'t take this back.'))) return false"
                       class="btn btn-danger btn-sm text-white"
                    >
                        Delete
                    </a>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

where is the mistake?

This is a simple REST API. i tried various combinations for @DeleteMapping, like @GetMapping and @RequestMapping. also, when i check the mysql terminal, it doesn't delete the chosen patient.

thank you.


Solution

  • A 404 is is always because the path in your thymeleave page, namely /patients/delete(patientId=${patient.getPatientId()}) is not found in your controller. Your controller only contains /delete, /register_patient, /save & /view_database. I can see the http://localhost:3000/view_database works fine so it is using the correct path. Change /patients/delete to /delete

    The 404 has nothing to do the the @Entity or @Repository code.

    As regards using @DeleteMethod, you can’t for this reason. You will get a 405 (method not allowed). Try @PostMethod.

    Use Postman to confirm your urls/paths before attempting to call from thymeleaf/html