【发布时间】:2021-03-06 20:44:44
【问题描述】:
我有一个简单的例子来说明我的问题。有两个学生和三个科目。一开始student1有所有科目,student2没有科目。关系是一个学生和许多学科。
我正在尝试使用 jpa hibernate 将 subject1 从 student1 交换到 student2。数据库中出现事务提交更改后:主题表的外键student_id发生了更改,但在java中,即使我从数据库中加载student1,对象仍然有subject1。
@Entity
@Table(name = "STUDENTS")
public class Students {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ST_ID")
private int id;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
List<Subject> subjects = new ArrayList<>();
//getters and setters....
}
@Entity
@Table(name = "SUBJECT")
public class Subject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SB_ID")
private int id;
@Column(name = "MARK")
private int mark;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "ST_ID")
private Students student;
//getters and setter....
}
主要代码:
public static void main(String[] args) throws Exception {
EntityManager em = Persistence.createEntityManagerFactory("Test").createEntityManager();
// em.getTransaction().begin(); //does not work
Students student1 = getStudentById(1, em); //load student1 from database by id
Students student2 = getStudentById(2, em); //load student2 from database by id
Subject subject1 = getSubjectById(1, em); //load subject1 from database by id
Subject subject2 = getSubjectById(2, em); //load subject2 from database by id
Subject subject3 = getSubjectById(3, em); //load subject3 from database by id
System.out.println("student1 subjects");
for(Subject sb : student1.getSubjects()){
System.out.println(sb.getId()); //prints subjects: 1,2,3
}
System.out.println("\nstudent2 subjects");
for(Subject sb : student2.getSubjects()){
System.out.println(sb.getId()); //prints no subjects
}
//swap subject1 between student1 and student2
subject1.setStudent(student2);
student2.getSubjects().add(subject1);
//save changes
em.getTransaction().begin();
em.persist(student2);
em.persist(student1);
em.persist(subject2);
em.persist(subject1);
//em.merge does't work
//em.flush(); //doesn't work
em.getTransaction().commit();
student1 = getStudentById(1, em); //load student1 from database by id
System.out.println("\nstudent1 subjects");
for(Subject sb : student1.getSubjects()){
System.out.println(sb.getId()); //and still student1 has subject1
}
student2 = getStudentById(2, em); //load student2 from databse by id
System.out.println("\nstudent2 subjects");
for(Subject sb : student2.getSubjects()){
System.out.println(sb.getId()); //now student2 also has subject1
}
}
public static Students getStudentById(int id, EntityManager em){
Query query = em.createQuery("from entity.Students where ST_ID="+id);
return (Students)query.getSingleResult();
}
public static Subject getSubjectById(int id, EntityManager em){
Query query = em.createQuery("from entity.Subject where SB_ID="+id);
return (Subject) query.getSingleResult();
}
提交后的主题表如下所示。它显示 id 为 1 的科目现在有 id 为 2 的学生。
实体对象student1只有在我提交后em.refresh才会更新,但我不明白为什么我从数据库加载student1时需要使用refresh?而且我也不确定,刷新实体是好习惯吗?
【问题讨论】: