user2313232
user2313232

Reputation: 77

Hibernate: Insert records to tables(one-to-many relationship)

I have the following tables in my database.

Course Table

----------------------
|course_id|coursename|
----------------------
|    1    |   java   |
----------------------
|    2    |   c++    |
----------------------

Course_Student Table

----------------------
|course_id|student_id|
----------------------

Student Table

------------------------
|student_id|studentname|
------------------------

The relationship I am using is one-to-many. A student can register for many courses.

What I want to achieve is, if a student(jane) register for a course, the record will be inserted to Student and Course_Student table. if the same student(jane) register for another course, the student record will not be inserted to Student table but Course_Student table only.

As I am new to hibernate, I am not really sure how can I implement the requirements stated above. please help me. thank you.

Student POJO Class

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

public class Student {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column
    int student_id;
    @Column
    String studentname;

    public Student(int student_id, String studentname) {
        this.student_id = student_id;
        this.studentname = studentname;
    }

    public int getStudent_id() {
        return student_id;
    }

    public void setStudent_id(int student_id) {
        this.student_id = student_id;
    }

    public String getStudentname() {
        return studentname;
    }

    public void setStudentname(String studentname) {
        this.studentname = studentname;
    }

    @Override
    public String toString() {
        return "Student [student_id=" + student_id + ", studentname=" + studentname + "]";
    }
}

Course POJO Class

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

public class Course {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column
    int course_id;
    @Column
    String coursename;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    List<Student> student = new ArrayList<Student>();

    public Course(int course_id, String coursename, List<Student> student) {
        this.course_id = course_id;
        this.coursename = coursename;
        this.student = student;
    }
    public int getCourse_id() {
        return course_id;
    }
    public void setCourse_id(int course_id) {
        this.course_id = course_id;
    }
    public String getCoursename() {
        return coursename;
    }
    public void setCoursename(String coursename) {
        this.coursename = coursename;
    }
    public List<Student> getStudent() {
        return student;
    }
    public void setStudent(List<Student> student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Course [course_id=" + course_id + ", coursename=" + coursename + ", student=" + student + "]";
    }   
}

HibernateUtils CLass

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory sessionFactory = null;

    private static SessionFactory getSessionFactory() {
        if(sessionFactory==null)  {
            //Locate and read hibernate.cfg.xml file default in src/main/java
            sessionFactory = new Configuration().configure().buildSessionFactory();
            return sessionFactory;


        }
        else {
            return sessionFactory;
        }
    }

    public static Session getCurrentSession() {
        return getSessionFactory().getCurrentSession();
    }

    public static Session openSession() {
        return getSessionFactory().openSession();
    }

    public static void closeSession(Session session) {
        if(session.isOpen()) {
            session.clear();
        }
    }
}

Application Class

import org.hibernate.Session;

public class Application {

    //a student can apply many courses
    public static void applyCourse(String coursename, String studentname) {
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        Course course = session.get(Course.class, coursename);

        //not sure how to implement this part please help
        for(int i =0; i < course.getStudent().size(); i++) {
            if(course.getStudent().get(i).getStudentname().equals(studentname)) {
                //if student record exist,add to Course_Student table but don't add to Student table
            }
            else {
                //if student record doesn't exist,add to Course_Student table and Student table
            }
        }
        session.save(course);
        HibernateUtils.closeSession(session);
    }


    public static void main(String[] args) {
        Application.applyCourse("java", "jane");
        Application.applyCourse("c++", "jane");

    }
}

Upvotes: 2

Views: 1417

Answers (1)

JB Nizet
JB Nizet

Reputation: 691635

Your association is the typical example of a many-to-many: each student registers to several courses, and each course is attended by several students. So it should be ManyToMany, not OneToMany.

Moreover, cascade=ALL does not make sense in this case: if you delete a course, you don't want all the students attending the course to be deleted too. You should remove the cascade.

Also:

List<Student> student

It's a list. It contains several students. So you should name it students, not student. Naming it student is very confusing: i gives the feeling that a course is attended by a single student. Choose better names. The same student shouldn't be attending the same course several times, and the order of the students in the course doesn't matter, so you should use a Set<Student> rather than a List<Student>

Course course = session.get(Course.class, coursename);

This is not correct. Session.get() takes the unique identifier as argument. Not the course name. You need to pass the ID if the course, not its name. Or you need a query (using HQL) to find the course(s) with that name.

    //not sure how to implement this part please help
    for(int i =0; i < course.getStudent().size(); i++) {
        if(course.getStudent().get(i).getStudentname().equals(studentname)) {
            //if student record exist,add to Course_Student table but don't add to Student table
        }
        else {
            //if student record doesn't exist,add to Course_Student table and Student table
        }
    }

This is not the correct logic here. You shouldn't look for the student only in the course's students. Otherwise, you will only find students which are already registered to the course. Most probably, the student already exists, but is not registered to the course yet. You shouldn't recreate the student in that case. So the correct logic would be

Student student = findStudentByName(studentName);
if (student == null) {
    student = createStudent(studentName);
}
course.addStudent(student);

Note that even if the student already exists, and already attends the course, adding it again to the course isn't a problem: since the collection is a Set<Student>, adding it again won't modify the set.

Upvotes: 3

Related Questions