0

So, i write spring boot Controller, write Entity -> Course, write html views-> courses, but my information did not view in my template.

@Controller
@RequestMapping ("/courses")
public class CourseController {
    
    private CourseService courseService;
    public CourseController(CourseService courseService) {
        this.courseService = courseService;
    }
    
    
    @GetMapping ("/index")
    public String getCourses (Model model, @RequestParam (name="keyword", defaultValue = "") String keyword ) {
        List <Course> courses = courseService.findCourseBycourseName(keyword);
        model.addAttribute("listCourses", courses);
        model.addAttribute("keyword", keyword);
        return "views/courses";
        
    }

HTML + Thymeleaf courses.html -> when I start app loaded only empty table.

<tbody> 
<tr class ="text-center" th:each="course : ${listCourses}" > 
  <td th:text = "${course.getCourseId()}"> </td>
  <td th:text = "${course.getCourseName()}"> </td>
  <td th:text = "${course.getCourseDuration()}"> </td>
  <td th:text = "${course.getCourseDescription()}"> </td>
  <td th:text = "${course.getInstructor().getInstructorFirstName()} + '' + course.getInstructor().getInstructorLastName"> </td>
  <td th:text = "${course.getListStudent().size()}"> </td>

</tbody>
</table>

There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class. There is my Course Class.

@Entity
@Table (name = "courses")
public class Course {
    
    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    @Column (name = "course_id", nullable=false)
    private Long courseId;
    
    @Basic 
    @Column (name = "name", nullable=false, length = 45)
    private String courseName;
    @Basic
    
    @Column (name = "duration", nullable=false, length = 45)
    private String courseDuration;
    
    @Basic
    @Column (name = "description", nullable=false, length = 45)
    private String courseDescription;
    
    @ManyToOne (fetch = FetchType.LAZY)
    @JoinColumn (name = "instructor_id", referencedColumnName = "instructor_id", nullable = false)
    private Instructor instructor;
    
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable (name = "enrolled_in", 
                                     joinColumns = {@JoinColumn (name = "course_id")}, 
                                     inverseJoinColumns = {@JoinColumn (name = "student_id")})
    private Set<Student> listStudent = new HashSet<>();

    @Override
    public int hashCode() {
        return Objects.hash(courseId, courseName, courseDuration, courseDescription);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null || getClass() != obj.getClass())
            return false;
        Course course = (Course) obj;
        return courseId.equals(course.courseId) && Objects.equals(courseName, course.courseName) && Objects.equals(courseDuration, course.courseDuration) && Objects.equals(courseDescription, course.courseDescription);
    }

    // add object student to the list students;
    // add course to the List of Students;
    public void assignStudentToCourse (Student student) {
        this.listStudent.add(student);
        student.getCourses().add(this);

    }
    
    // remove student from course
    
    public void removeStudents (Student students) {
        this.listStudent.remove(students);
        students.getCourses().remove(this);
    }
    

    public Course () {}
    
    public Course(String courseName, String courseDuration, String courseDescription, Instructor instructor) {
        this.courseName = courseName;
        this.courseDuration = courseDuration;
        this.courseDescription = courseDescription;
        this.instructor = instructor;
    }

    public Long getCourseId() {
        return courseId;
    }

    public void setCourseId(Long courseId) {
        this.courseId = courseId;
    }

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getCourseDuration() {
        return courseDuration;
    }

    public void setCourseDuration(String courseDuration) {
        this.courseDuration = courseDuration;
    }

    public String getCourseDescription() {
        return courseDescription;
    }

    public void setCourseDescription(String courseDescription) {
        this.courseDescription = courseDescription;
    }

    public Instructor getInstructor() {
        return instructor;
    }

    public void setInstructor(Instructor instructor) {
        this.instructor = instructor;
    }

    public Set<Student> getListStudent() {
        return listStudent;
    }

    public void setListStudent(Set<Student> listStudent) {
        this.listStudent = listStudent;
    }

    @Override
    public String toString() {
        return "Course [courseId=" + courseId + ", courseName=" + courseName + ", courseDuration=" + courseDuration
                + ", courseDescription=" + courseDescription + "]";
    }
}

Who knows where problem

  • 1
    Does the method `courseService.findCourseBycourseName()` return anything? Maybe check with a debugger if the `courses` list has items? – Wim Deblauwe Jan 02 '23 at 14:07
  • so i don know, how work this tutorials, but i change method List courses = courseService.findCourseBycourseName(keyword) ---- > courseService.findAll(); and everything work good! –  Jan 02 '23 at 15:45
  • Can you paste your CourseService? – riddle_me_this Jan 02 '23 at 16:40
  • public interface CourseService { Course loadCourseBycourseId (Long courseId); Course createCourse (String courseName, String courseDuration, String courseDescription, Long instructorId); Course createOrUpdateCourse(Course course); List findCourseBycourseName(String keyword); void assignStudentToCourse (Long courseId, Long studentId); List fetchAll(); List fetchCourseForstudentId (Long studentId); void removeCourse (Long courseId); –  Jan 03 '23 at 15:20
  • Could you help me, please, with that. My method fetchAll() show me this course, but i can not find, method findByCourseName did not show course, but i can find. I merge this method in Controller @GetMapping ("/index") public String findCourse (Model model, RequestParam (name="keyword", defaultValue = "") String keyword ) { List courses = courseService.findCourseBycourseName(keyword); List course = courseService.fetchAll(); model.addAttribute("listCourses", course); model.addAttribute("keyword", keyword); return "views/courses"; } and work method fetch –  Jan 04 '23 at 18:23

1 Answers1

0

You need to close your tag in your HTML snippet.

<tbody> 
<tr class ="text-center" th:each="course : ${listCourses}" > 
  <td th:text = "${course.getCourseId()}"> </td>
  <td th:text = "${course.getCourseName()}"> </td>
  <td th:text = "${course.getCourseDuration()}"> </td>
  <td th:text = "${course.getCourseDescription()}"> </td>
  <td th:text = "${course.getInstructor().getInstructorFirstName()} + '' + course.getInstructor().getInstructorLastName"> </td>
  <td th:text = "${course.getListStudent().size()}"> </td>
</tr><!-- bingo -->
</tbody>
</table>

Also see How to print Array size in thymeleaf? because it might be your next question.

In your service class, make sure that you have @Repository as an annotation. Each method name needs to reflect the property, in a case-sensitive camelCase format. You should also rename it to CourseRepository to better describe what it is doing. Note the difference:

@Repository
public interface CourseRepository extends CrudRepository <Course, Long> {

    Iterable<Course> findByCourseName(String courseName);

    //other ones    
    
    //CrudRepository will give you these two so you don't need to add them:
    //Iterable<Course> findAll();
    //Optional<Course> findById(Long courseId);    
}

You can look at CrudRepository or JPARepository to extend depending on your needs. Info here and here.

More modern design shows these queries returning with Java's Optional but this should not be the cause of your error.

(Also, in the future, you can just update the question with the code instead of commenting it.)

https://github.com/vphilipnyc/forvladislav

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80
  • so i dont know, how work this tutorials, but i change method List courses = courseService.findCourseBycourseName(keyword) ---- > courseService.findAll(); and everything work good! –  Jan 02 '23 at 15:44
  • Did you check the keyword you are providing? What is returned if the service is given a null or empty string as the keyword? For JPA repositories, you should also check that the method has the right case (e.g., "findCourseByCourseName" would be correct if the property is called courseName) – riddle_me_this Jan 02 '23 at 16:35
  • 1
    And you will still want to close that HTML tag since it is malformed. – riddle_me_this Jan 02 '23 at 16:42
  • Please could you help me with that. Why my List did not view in application –  Jan 04 '23 at 18:21
  • If you are still having issues, update your question with the Course class too since that will describe how you have your properties set up. – riddle_me_this Jan 05 '23 at 06:20
  • I update and added Course class, if you can please help me solve this issues, tnx –  Jan 06 '23 at 06:12
  • https://github.com/vphilipnyc/forvladislav – riddle_me_this Jan 06 '23 at 17:56
  • Oh Big thanks!! these is real help me, solve my problem. You good It specialist –  Jan 11 '23 at 07:58