本文介绍了用于一对多调用的SQL“更新"的休眠级联删除.而不是“删除"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了一个简单的父/子obj双向关系.我要执行级联删除,以便在删除父级时,也可以通过父级的1个删除调用来删除所有子级.这是我的pojo类声明:

I have a simple parent / children obj bi-directional relationship defined. I want to perform cascade delete so that when parent is removed, all the children would be removed as well with one 1 delete call from parent. Here are my pojo class declaration:

@Entity
@Table(name = "Agent_Assignment", schema = "xxx", catalog = "AAA")
public class AgentAssignment {
    private Set<AgentAssignmentAttr> attributes = new HashSet<AgentAssignmentAttr>();

    @OneToMany( fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true )
    @JoinColumn(name="Agent_Assignment_GUID")
    public Set<AgentAssignmentAttr> getAttributes() {
        return attributes;
    }

    public void setAttributes(Set<AgentAssignmentAttr> attributes) {
        this.attributes = attributes;
    }

}

@Entity
@Table(name = "Agent_Assignment_Attr", schema = "xxx", catalog = "AAA")
public class AgentAssignmentAttr {
    private AgentAssignment asgnmnt = null;

    @ManyToOne( fetch=FetchType.EAGER )
    @JoinColumn(name="Agent_Assignment_GUID", insertable=false, updatable=false)
    public AgentAssignment getAssignment() {
        return asgnmnt;
    }

    public void setAssignment(AgentAssignment assignment) {
        this.asgnmnt = assignment;
    }
}

要删除的代码是:

AgentAssignment assgnmnt = (...some HQL query to returns the AgentAssignment obj)
getSession().delete(assgnmnt);

执行上述删除调用时,它将引发异常:

When execute the above delete call, it throws exception:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

基本上,在执行Hibernate日志的SQL日志时,它不会在应删除的Agent_Assignment_Attr表行上调用"update",而是在该行上调用"update"以设置外键列"Agent_Assignement_GUID"为null,如下所示:

Basically, when log at the Hibernate log's SQL being executed, it doesn't call "update" on Agent_Assignment_Attr table's row it supposed to delete, but instead call "update" on the row to set the foreign key column "Agent_Assignement_GUID" to null, as shown below:

/* delete one-to-many com.cs.mytime.acr.model.AgentAssignment.attributes */ update
        MyTime.dbo.Agent_Assignment_Attr 
    set
        Agent_Assignment_GUID=null 
    where
        Agent_Assignment_GUID=?
2014/08/22 16:31:10.430 [TRACE] <http-bio-8080-exec-5> (BasicBinder.bind:81) - binding parameter [1] as [VARCHAR] - [CA91A4F3-6F7E-4188-B299-8E9DF17F0385]

感谢任何人来帮助我看看是否有我错过的事情以及正确的解决方案.谢谢.

Appreciate anybody to help to see if there's something I have missed and the right solution. Thanks.

推荐答案

您的映射错误.双向关联只能定义一次映射方式.您所拥有的是两个完全不同的,不相关的关联,它们恰好使用同一列.映射应该是

Your mapping is wrong. A bidirectional assocition must only define how the association is mapped once. What you have there is two distinct, unrelated associations that happen to use the same column. The mapping should be

@OneToMany(mappedBy="assignment", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true )
public Set<AgentAssignmentAttr> getAttributes() {
    return attributes;
}

其中 mappedBy 说:我是双向关联的反面,该​​双向关联在 AgentAssignmentAttr.assignment 上定义和映射,并且

where mappedBy says: "I'm the inverse side of the bidirectional association defined and mapped on AgentAssignmentAttr.assignment, and

@ManyToOne( fetch=FetchType.EAGER )
@JoinColumn(name="Agent_Assignment_GUID")
public AgentAssignment getAssignment() {
    return asgnmnt;
}

这篇关于用于一对多调用的SQL“更新"的休眠级联删除.而不是“删除"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 02:27