OneToMany Hibernate 保存级联问题

Posted

技术标签:

【中文标题】OneToMany Hibernate 保存级联问题【英文标题】:OneToMany Hibernate Save Cascade Problems 【发布时间】:2014-07-16 02:27:50 【问题描述】:

我正在处理 Hibernate 和 OneToMany 关系,我今天遇到了一个奇怪的行为,虽然我是故意这样做的,但我没有预料到这种行为

College.java

@Entity
@Table(name="COLLEGE")
public class College implements Serializable
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="COLLEGE_XID")
    private Long collegeId;

    @Column(name="COLLEGE_NAME")
    private String collegeName;

    @OneToMany(mappedBy="college",cascade = CascadeType.ALL) 
    private List<Student> studentList = new ArrayList<Student>();
    //... with get and setters

学生.java

@Entity
@Table(name = "STUDENT")
public class Student implements Serializable    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="STUDENT_XID")
    private Long studentId;

    @Column(name="STUDENT_NAME")
    private String studentName;

    @ManyToOne
    @JoinColumn(name="COLLEGE_XID",nullable=false)
    private College college;
    //... with get and setters

应用程序.java

    College college1 = new BdCollege();
    college1.setCollegeName("C_1");

    College college2 = new BdCollege();
    college2.setCollegeName("C_2");

    Student student1 = new BdStudent();
    student1.setStudentName("S_1_C_2");

    CollegeDAO collegeDAO = new  CollegeDAO();

    // setting student 1 Parent to College 1        
    student1.setCollege(college1);   // <---- Here the Issue  ... student 1 as college 1 child

    // BUT assigning Student 1 as Child of Collge 2 in List 
    // i did it purposely to test the behaviour
    college2.getStudentList().add(student1);  // <---- Here the Issue ... but assigning it in the list of College 2 ... ws expecting Exception 

     // Saved College 1 & 2
     collegeDAO.save(college1);
     collegeDAO.save(college2);

      // Saved Successfully BUT

结果 大学表

 COLLEGE_XID     COLLEGE_NAME    
 --------------  --------------- 
 1               C_1             
 2               C_2 

学生桌

 STUDENT_XID     STUDENT_NAME     COLLEGE_XID    
 --------------  ---------------  -------------- 
 1               S_1_C_2          1   

我期待一些例外,因为孩子和父母在大学里的作业不匹配 - 学生示例 另一件困扰我的事情是hibernate生成的查询

Hibernate: insert into COLLEGE (COLLEGE_NAME) values (?)
Hibernate: insert into COLLEGE (COLLEGE_NAME) values (?)
Hibernate: insert into STUDENT (COLLEGE_XID, STUDENT_NAME) values (?, ?)

即它首先保存大学 1,然后保存大学 2,然后将学生保存为大学 2 的孩子,但结果显示为大学 1 的孩子

【问题讨论】:

“把学生当成大学的孩子2”你怎么能确定这一点。您只看到没有值的 SQL。可能是说首先是college_xid为1的学生。 @shazin 好吧,这确实不确定,并且 :) 这不是真正的问题,对于您的评论,我尝试过不同的情况,Hibernate 按保存对象的顺序生成 SQL... 这是因为您没有在任何地方设置任何级联。因为您在@ManyToOne 上指定了@JoinColumn,所以存在一列供Hibernate 创建一个插入语句。但是因为 Hibernate 不知道如何将你的学生列表映射回你的持久学生对象,所以它不能用它做任何事情。只是我的 0.02 美元 @JamesMassey @OneToMany(mappedBy="college",cascade = CascadeType.ALL) 级联映射到College Class Herp derp,错过了。也许 Hibernate 将连接列作为级联的优先级。 【参考方案1】:

这是因为您添加了 mappedBy 属性并使学生成为关联的所有者。 由于 Student 实体是所有者,它将保持关系,hibernate 将忽略 College 方面的更改。

【讨论】:

以上是关于OneToMany Hibernate 保存级联问题的主要内容,如果未能解决你的问题,请参考以下文章

OneToMany Hibernate 保存级联问题

如何使用 Spring Data / Hibernate 级联保持 @OneToMany 与 @EmbeddedId 的关系

Hibernate 从 onetomany 中删除

Symfony2/Doctrine:如何使用 OneToMany 将实体重新保存为级联新行

Spring Data JPA:保存嵌套的 OneToMany 子级(具有级联)返回 NULL 父级外部对象

hibernate级联配置