Hibernate Annotation映射,JPA Orphan Delete

时间:2014-09-23 13:55:17

标签: java hibernate jpa hibernate-annotations

我尝试在类别和出版物类(OneToMany)之间建立关系,我需要删除属于特定类别的所有出版物。 我不知道我是否遗漏了一些注释,但执行查询时这是我的错误:

  

org.springframework.web.util.NestedServletException:Request   处理失败;嵌套异常是   org.hibernate.exception.ConstraintViolationException:不能   执行更新查询     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)     javax.servlet.http.HttpServlet.service(HttpServlet.java:618)     org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)     javax.servlet.http.HttpServlet.service(HttpServlet.java:725)     org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

     

org.hibernate.exception.ConstraintViolationException:不能   执行更新查询。

     

org.postgresql.util.PSQLException:错误:在表格上更新或删除   "类别"违反外键约束" fkf5bea17d42c4af41"桌子上   "出版物"细节:仍然引用了键(id)=(190)   表"出版物"。

我的源代码如下:

分类:

@Entity
@Table(name = "category")
public class Category {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String name;
    private String description;

    @OneToMany(mappedBy="category", orphanRemoval=true)
    private List<Publication> publications;

    // Getters and Setters
}

出版课程:

@Entity
@Table(name = "Publication")
public class Publication {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String title;
    private String content;

    @ManyToOne
    @JoinColumn(name = "id_category")
    private Category category;

    // Getters and Setters
}

查询删除类别:

@Override
public void deleteCategory(int id) {
    sessionFactory.getCurrentSession()
     .createQuery("DELETE FROM Category WHERE id="+id).executeUpdate();
}

先谢谢大家。

2 个答案:

答案 0 :(得分:0)

您需要将删除操作级联到发布:

@OneToMany(mappedBy="category", orphanRemoval=true, cascade = CascadeType.ALL)
private List<Publication> publications;

<强> 编辑:

由于添加级联并没有解决您的问题并且您正在使用Hibernate,因此为级联添加特定于Hibernate的注释可能会有所帮助。在这种情况下,您不需要上面的JPA参数:

@OneToMany(mappedBy="category", orphanRemoval=true)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.ALL)
private List<Publication> publications;

这会破坏对不同对象关系映射框架的可移植性,因为它不再是纯粹的JPA - 但在过去的某些情况下它帮助了我。

答案 1 :(得分:0)

即使你把级联,它也行不通。我从您的问题中看到,您要删除某个类别的所有出版物,然后您的查询应更改为以下内容。 (您之前尝试删除类别)

delete from Publication p where p.category.id = :categoryId;

然后,如果您还想删除Categories。 (现在您可以安全地删除类别,因为Publication表中没有引用。

delete from Category c where c.id = :categoryId;