简体   繁体   中英

JPA: cascade in table association relationship

I have three tables one to hold student information, second which holds class information. Third is to associate the student and class studentclass table

The entities and relationships are given below

class Student
{
@Id
@Column(name="STUDENT_ID")
long studentId;
@OneToMany(cascade=CascadeType.ALL,mappedBy="student")
Set<StudentClass> studentClasses
}

class Class
{
@Id
@Column(name="CLASS_ID")
long classId;

@OneToMany(cascade=CascadeType.ALL,mappedBy="class")
Set<StudentClass> studentClasses
}    

class StudentClass
{
@Id
@Column(name="STUDENT_CLASS_ID")
long studentClassid;

@ManyToOne
@JoinColumn(name="STUDENT_ID")
private Student student;

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="CLASS_ID")
private Class class;
}

class persist{
public void persist(){
Student student1 = new Student();
Class class1 = new Class();

session.save(class1);    

StudentClass studentClass = new StudentClass();
studentClass.setClass(class1);
studentClass.setStudent(student1);
student1.getStudentClasses().add(studentClass);
session.save(student1);      
session.getTransaction().commit();
}
}

The above persistence logic works fine as I save class1 separately and finally student class. But if I try to do save student1 alone the class1 is not getting saved? If the answer is class and students are not directly related then how retrieval gets all the classes when I try to fetch a student

First, i think you need have your Entities classes annoted with @Entity. With your entity StudentClass hasn't any attribute for justify you coded then, only map your entities Student and Class with @ManyToMany like in this: http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany If you need retrieval gets all the classes when to fetch a student set the attribute to the FetchType to FetchType.EAGER need more in Difference between FetchType LAZY and EAGER in Java Persistence API?

The cascade mapping you used will be working fine with JPA EntityManager operations persist() or merge() . However it looks like you are using Hibernate session to save objects. With this approach you also need to add Hibernate specific annotation @Cascade(CascadeType.SAVE_UPDATE) for class field.

You dont need to create a separate entity called StudentClass. You can make use of @JoinTable to let it create for you. This will handle your case of not updating the values by itself.

Remove the class and add

@OneToMany(mappedBy = "Student")
@JoinTable(name = "StudentClass", joinColumns = @JoinColumn(name = "StudentId"),
   inverseJoinColumns = @JoinColumn(name = "ClassId"))
private Collection<Class> classes;
}

Also, alternate way would be to update the Student table to include the Class information so that the tables look like - 1. Table - Student(StudentId, StudentName, ClassId) 2. Table - Class(ClassId, ClassName)

PS - I would also suggest renaming Class with Course :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM