Reputation: 77
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
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