idkwat2do
idkwat2do

Reputation: 458

How to get specific id from database using jpa?

Basically what I have working now is I have a few different .jsp's for a school. I can add courses and I can add students and also add students to specific courses. What I would like to learn is how would I go about showing only the students for what ever specific course the user(me) clicks.

        <form action="http://localhost:8080/School/add" method="POST">
        Kurs:
        <select name="coursedrop">
            <c:forEach items="${allCourses}" var="course">
                <option value="${course.id}">${course.id}: ${course.coursename}</option>
            </c:forEach>
        </select>
        Student:
        <select name="studentdrop">
            <c:forEach items="${allStudents}" var="student">
                <option value="${student.id}">${student.id}: ${student.studentname}</option>
            </c:forEach>
        </select>
        <input type="submit" value="Add"/>
    </form>

The form shown above are two drop-down lists, one for course and the other for student. I can for example add student nr.3 to course nr.5 to my database. So at least that works..

My next step is showing the specific students for their specific courses. What I have is one .jsp page that lists all the courses as clickable links. Like this:

<tbody>
    <c:forEach items="${allCourses}" var="course">
       <tr>
          <td><a href="http://localhost:8080/School/course?id=${course.id}">${course.coursename}</a></td>
       </tr>
     </c:forEach>
 </tbody>

When I click one of the links, aka coursenames, I get to another .jsp page that currently lists all the students, even if they aren't in the specific course that I clicked on.

This is what my servlet looks like. (Im sorry if it's horrible)

    @Inject
SchoolBoundary sb;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    String path = request.getServletPath();
    String redirect = "/home.jsp";
    String forward = null;
    switch(path) {
        case "/student":
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/student.jsp";
            break;
        case "/course":
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/course.jsp";
            break;
        case "/add":
            request.setAttribute("allCourses", sb.getAllCourses());
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/add.jsp";
            break;
        case "/home":
            request.setAttribute("allCourses", sb.getAllCourses());
            forward = "/home.jsp";
            break;
        default:
            request.setAttribute("allCourses", sb.getAllCourses());
            forward = "/home.jsp";
    }
    request.getRequestDispatcher(forward).forward(request, response);

I can see that my "getAllStudents" will show all of the students and not by id (which is what I think I need but I dont know how..). And my "getAllStudents" from my boundary:

    public Set<Student> getAllStudenter() {
    return new HashSet(studentFacade.findAll());
}

recap. I want to be able to show only the students that are in each specific course and not all students in all courses. Thanks for any help :(

Upvotes: 1

Views: 439

Answers (2)

stg
stg

Reputation: 2797

First of all I would recomend not to use an embedded PK (unless you really have to highly optimize the database model or you are not able to change the existing model because it is out of your responsibilities). You will have almost the same behaviour if you add a simple ID (e.g. of tyoe Long) and add a unique constraint on the fields for the course ID and student ID. It will need more memory in the database but unless we are not talking about very lots of rows in this "join table" this extra memory is negliable. But what you get in return is an entity model that is much more easy to handle.

If you want to get all Student that are attending to a particular course you may write a simple JPQL query for that.

First get the Reference for the course. After that query for all students in Kursinfo where the course is equals to the course that you are interested in. Basically like this (it is not tested and may contain minor bugs, but I want to show you the general idea):

String query = "SELECT k.student FROM Kursinfo k WHERE k.kurs = :kurs";
TypedQuery<Student> q = entityManager.createQuery(query, Student.class);
q.setParameter("kurs", entityManager.getReference(kursId, Kurs.class));
return q.getResultList();

Upvotes: 1

blurfus
blurfus

Reputation: 14031

You need to implement a method called findAllByCourseId(Long courseId) in your back-end (not the servlet) - similar to something like this:

public Set<Student> findAllByCourseId(Long courseId) {
    return new HashSet(studentFacade.findAllByCourseId(courseId));
}

Then you need to open the StudentFacade (which I am not sure, but it could be an interface and add a definition to this method. Like:

Set<Student> findAllByCourseId(Long courseId);

Finally, add the implementation of the interface (if there is one) and implement the new method. Something along the lines of:

// filter the all list or use your own query
public Set<Student> findAllByCourseId(Long courseId) {
    // this is filtering
    List<Student> allStudents = findAll();
    List<Student> filteredList = new ArrayList<Student>();

    for(Student student : allStudents ){
        if( student.getCourseId() == courseId ){
           filteredList.add(student);
        }
    }

    return new HashSet(filteredList);
}

Upvotes: 0

Related Questions