@Entity
@Table(name="u_group")
public class Group {

private int id;
private String name;
private int age;
private Set<User> users=new HashSet<User>(); @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @OneToMany
@Cascade(value={CascadeType.DELETE})
public Set<User> getUsers() {
return users;
} public void setUsers(Set<User> users) {
this.users = users;
}
}
@Entity
public class User {

private int id;
private String name;

@Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}@Test
public void testGroup_User(){
Group g=new Group();
g.setId(3); Session session=sessionFactory.getCurrentSession();
session.beginTransaction();
session.delete(g);
session.getTransaction().commit();

}
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`hibernate/user`, CONSTRAINT `FK285FEB5156FC9E` FOREIGN KEY (`group_id`) REFERENCES `u_group` (`id`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1269)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:955)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 28 more
Hibernatedelete

解决方案 »

  1.   

    没用过hibernate,sql层面上是因为user这个table里有个FK禁止删除
    但总觉得这个cascade规则应该用在ManyToOne一侧
      

  2.   


    我现在写的是一对多关联,多对多关联还没写,我试下吧
    不是多对多,是多对一,也就是一对多的反面,一个一对多的关系必定跟着一个多对一,只是可能是隐性的没有被声明在entity里在你的情况就是在user这个entity里的group属性
      

  3.   


    我现在写的是一对多关联,多对多关联还没写,我试下吧
    不是多对多,是多对一,也就是一对多的反面,一个一对多的关系必定跟着一个多对一,只是可能是隐性的没有被声明在entity里在你的情况就是在user这个entity里的group属性我写了多对多情况是可以级联删除的,我想分别一对多,多对一级联删除
      

  4.   


    用hibernate建的表,没看。不过我多对多关联能级联删除应该是OK的
      

  5.   


    用hibernate建的表,没看。不过我多对多关联能级联删除应该是OK的
    你这个删不掉是因为发现了有其他表引用了这个表,而你删除的时候只给了ID。
    应该先将ID为3的先查询出来,再delete,因为你只给了ID=3
      

  6.   

    这个啊,你group中的映射文件应该是设置了Inverse="true",当删除group的时候,不会控制与user的关系,因此会报错!外键约束错误!你如果把inverse="false",那么不会报错,会控制user的关系,会发update set 
    groupId=null where groupId=null;
    建议删除group的时候先load一下,然后再delete就不会报错了
      

  7.   

    一对多,多对一是同一个关系的两侧,User侧是多对一,Group侧是一对多,最终在sql里只会在子表也就是user表里加入个FK 
    如果你想当一个group被删除时所有这个group里的Users都被删除则在onDelete的Constraint里cascade不可能当删除一个User时删除他的Group所以我觉得是应该在User侧也就是你的ManyToOne那里声明cascade
      

  8.   


    Session session=sessionFactory.getCurrentSession();
    session.beginTransaction();
    Group g=(Group)session.get(Group.class, 2);
    session.delete(g);
    session.getTransaction().commit();
    这个在一对多的情况下还是不行,到目前为止我是了很多方法,只有在User那边也设ManyToOne并级联才成功,也就是多对多的情况
      

  9.   

    我觉得你说的有点不对
    如果我group1里有2个User  一个U1,一个U2
    那么我删除U1的时候你就把group1删掉,那U2是不是也跟着被删掉了,可是我不想删U2
    ,所以我觉得应该设在OneToMany 的cascade  为delete
      

  10.   


    你就把group ID为3的先get出来  再delete  应该是OK的,
    你没查出来,hibernate就只知道你Group ID为3的里没有User,而删除时,他发现了,就报错了
    相反,你查出来了,他就发现了Group ID为3的里有User,然后他就会删除User
      

  11.   


    我说的一对多关联是:将id 为1 的group删掉,那么group 1 中的user都将删掉 
    而不是当删除一个User时删除他的Group,因为group可以有很多user
      

  12.   

    我觉得你说的有点不对
    如果我group1里有2个User  一个U1,一个U2
    那么我删除U1的时候你就把group1删掉,那U2是不是也跟着被删掉了,可是我不想删U2
    ,所以我觉得应该设在OneToMany 的cascade  为delete不知道有没有看过sql服务器里你设置的FK?
    当你有一个Group User 的OneToMany关系时,User这个table里会有一个group_id而这个group_id上会有一个FK constraint连接Group表的PK,而Group表没有任何User信息。我说的在ManyToOne侧定义这个constraint并不代表当删除一个User时要删除其Group(上个回复最后一句话),而是因为一个FK真正的定义是在这一侧,而他表示的意思也是,当被引用行(即Group表中的一行)被删除时,我该怎么办
      

  13.   

    总结一下:级联删除非得用多对多吗?(其他我试貌似都不可以,但save和get都是可以)!!!
    是这样吗????????????
      

  14.   

    我刚刚测试了下
    也许是因为你用的org.hibernate.annotations.CascadeType.DELETE
    我用的JPA的javax.persistence.CascadeType.REMOVE
    我这个可以,你那个我没试
      

  15.   

    我刚刚测试了下
    也许是因为你用的org.hibernate.annotations.CascadeType.DELETE
    我用的JPA的javax.persistence.CascadeType.REMOVE
    我这个可以,你那个我没试这个我试了,一对多失败,你是一对多吗?
      

  16.   

    我是这样配的@OneToMany(mappedBy="group",cascade={CascadeType.REMOVE})
    public Set<User> getUsers() {
    return users;
    } Session session = HibernateSessionFactory.getSession();
    session.beginTransaction();
    Group group = (Group) session.get(Group.class, 1L);
    session.delete(group);
    session.getTransaction().commit();
      

  17.   

    @ManyToOne
    public Group getGroup() {
    return group;
    }
      

  18.   

    多对多我成功了!在网上看了好多文章,差不多都是这样,一对多和多对多在数据库的表现是一样的,只是java中有点不一样!!!
      

  19.   

    多对多是要中间表的,用注解是@ManyToMany  我这个是1对多的双向
      

  20.   


    这两个很可能是一个概念,可以试着通过看源码验证
    Hibernate习惯用delete,JPA是remove,但一个意思,hibernate内部做了统一指向
      

  21.   


    这句话有问题,应该是inverse="false"就不会报错了的,这样就控制了关系,会发update t_user set groupId=null where groupId=?
      

  22.   

    OneToMany中有inverse属性吗,我怎么没找到??? 
      

  23.   

    是在set上的有inverse属性……oneTomany肯定没啦……
    再次建议你两种解决方案:一,set端设置inverse=false。
    二,删除group的时候load上来再删除,此时也必须设置级联……
      

  24.   

    OneToMany可以级联删除,但我觉得如果正确设置了不应该报Cannot delete or update a parent row: a foreign key constraint fails这个错误才对,因为它删除时是先删除Many方,再删除One方,顺序反过来才会报这种错误
      

  25.   

    我是Annotation写的,谁能直接给个例子什么的,一对多单向关联级联删除!!!
    网上好多都是xml配置文件写的,38楼的说的是xml配置文件里面的吧?
      

  26.   

    user是维护端,删除之前先把group置为空就ok了,以下是伪代码
    Group group=session.get(id);   //(id为groupid)
    for(User user:group.getUsers()){
    user.setGroup(null);
    }
    session.delete(group);
      

  27.   

    你去我博客上看,上面有一些总结,一对多关系的例子有好多……总之,学东西得慢慢来,你得弄清楚cascade与inverse,否则你永远也弄不清楚这里面的原理。
      

  28.   

    你为什么要纠结是用annation还是xml这两个根本就没区别,你太纠结了……
      

  29.   

    lz 都没有指定 多的一方的外键是那个字段,应该在User里加上@ManyToone标签并加上Group对象的引用
      

  30.   

    这不是纠结不纠结的问题,我只会Annotation,xml 不会!网上的确有很多例子,但大多都是xml的,Annotation的试了又错
      

  31.   


    上面说的什么啊 好多啊  一对多单向就单向喽
    首先 你的那个Group g=new Group(); g.setId(3);这哥们 是瞬时态  
    楼主是想根据 Id 删除某个group  还是里面的人也删除 
    要是删除 group  人留着 就 下边
    Group g=session.get(Group.class;"3"); 得到持久态
    Set<User> set=g.getSet();  得到里面所有的用户
    循环用户    的到每一个用户  user   user.setGroup(null); 断掉关系
    然后  session.delete(g);   删除 group如果要里面的user 全部删掉   就把取出来的 user    session.delete(user);级联关闭 手动先删掉关系  在删掉多的一方
      

  32.   

    本来被这个伤到了的,不想再想了。但看了一些意见去试了下天又发现了奇怪的事,我感觉没怎么改,但都成功了,怎么试怎么成功,以前试了好多方法都失败,现在都成功了!以至于我现在都不知道我当时是怎么错的??48楼说的应该可行我没试,因为可以直接delete(g)级联删除对应的user。谢谢楼上给位,问题解决,结贴!
      

  33.   

    整理了一下思路,one2many的级联删除按正常情况是可以的,hibernate级联删除时会自动将one方对many方的外键设为null,但如果one方的外键声明为非null的话,就无法级联删除,就会报a foreign key constraint fails这种错误此时的一种解决方法是设置inverse="true"并改为双向关联,这在Hibernate文档中有相应的描述:
    Very Important Note: If the <key> column of a <one-to-many> association is declared NOT NULL, Hibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) ed as inverse="true".