如何映射父子关系并在hibernate中进行适当的级联删除?

时间:2013-06-25 06:59:34

标签: java hibernate parent-child one-to-many cascade

我还没有列出与此问题无关的专栏。我将简要描述一下我想做什么,然后继续解释这个问题。我正在尝试在数据库中建模图形。每个顶点具有多个边(顶点 - >边:一对多),并且每个顶点物理Id被映射到唯一的顶点(一对一)。虚拟vertexIds和physicalResourceIds之间的这种映射是出于另一个目的。

Inshort,我的问题是我想在删除顶点时将删除级联到边缘,但是当我删除边缘时,我不想将删除级联到顶点。 我有一个有三个表的数据库,它们的模型类如下所示:

public class VertexModel implements java.io.Serializable{
/**
 * @return the mapping
 */
@OneToOne(mappedBy = "vertex", fetch = FetchType.EAGER, cascade = {CascadeType.ALL} )
public PhysicalResourceToVertexMappingModel getMapping() {
    return mapping;
}
/**
 * @param mapping the mapping to set
 */
public void setMapping(PhysicalResourceToVertexMappingModel mapping) {
    this.mapping = mapping;
}

/**
 * @return the edgeSet
 */
@OneToMany(mappedBy = "sourceVertex", fetch = FetchType.EAGER, cascade = {CascadeType.ALL} )
public Set<EdgeModel> getSourceEdgeSet() {
    return sourceEdgeSet;
}
/**
 * @param edgeSet the edgeSet to set
 */
public void setSourceEdgeSet(Set<EdgeModel> sourceEdgeSet) {
    this.sourceEdgeSet = sourceEdgeSet;
}

/**
 * @return the destinationEdgeSet
 */
@OneToMany(mappedBy = "destinationVertex", fetch = FetchType.EAGER, cascade = {CascadeType.ALL} )
public Set<EdgeModel> getDestinationEdgeSet() {
    return destinationEdgeSet;
}

/**
 * @param destinationEdgeSet the destinationEdgeSet to set
 */
public void setDestinationEdgeSet(Set<EdgeModel> destinationEdgeSet) {
    this.destinationEdgeSet = destinationEdgeSet;
}


public class EdgeModel implements java.io.Serializable {

/**
 * Gets the source vertex's vertex
 * @return the sourceVertex
 */
@ManyToOne(targetEntity = VertexModel.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "SOURCE_VERTEX_ID", nullable = false)
public VertexModel getSourceVertex() {
    return this.sourceVertex;
}
/**
 * Sets the source vertex
 * @param sourceVertex the sourceVertex to set
 */
public void setSourceVertex(VertexModel sourceVertex) {
    this.sourceVertex = sourceVertex;
}
/**
 * Gets the destination vertex
 * @return the destinationVertex
 */
@ManyToOne(targetEntity = VertexModel.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "DESTINATION_VERTEX_ID", nullable = false)
public VertexModel getDestinationVertex() {
    return this.destinationVertex;
}
/**
 * Sets the destination vertex
 * @param destinationVertex
 */
public void setDestinationVertex(VertexModel destinationVertex) {
    this.destinationVertex = destinationVertex;
}

public class PhysicalResourceToVertexMappingModel implements java.io.Serializable{

    /**
 * @return the vertex
 */
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="VERTEX_ID")
public VertexModel getVertex() {
    return vertex;
}

/**
 * @param vertex the vertex to set
 */
public void setVertex(VertexModel vertex) {
    this.vertex = vertex;
}

现在,我的问题是,当我删除一个顶点时,所有入射在这个顶点上的边也会被删除,这就是所希望的。但是,接下来发生的事情是不可取的当我删除边时,删除具有该边的所有顶点,然后这些顶点删除它们上的边缘事件,这会导致其他顶点被删除,依此类推。 基本上,孩子与父母之间的关系不能很好地映射。

简而言之,如果这是图表: V1(E1)V2(E2)V3(E3)V4其中V是顶点,E是边。现在,当我删除V1时,E1被删除,这是预期的。但是,V2也会被删除(因为E1被删除了)然后,V2被删除等等,整个图形被删除。

我在这里做错了什么?我的父子映射(使用@mappedBy)是错误的吗?我的删除代码如下:

        Session session = this.getCurrentSession();

    Criteria criteriaVertex = session.createCriteria(VertexModel.class);
    Criteria criteriaMapper = session.createCriteria(PhysicalResourceToVertexMappingModel.class);
    criteriaMapper.createAlias("vertex", "vertex")
                    .add(Restrictions.eq("vertex.clientId", clientId))
                    .add(Restrictions.eq("vertex.nodeId", nodeId ))
                    .add(Restrictions.eq(Constants.Columns.PHYSICAL_ID, physicalId));

    PhysicalResourceToVertexMappingModel resultMapping = (PhysicalResourceToVertexMappingModel) criteriaMapper.uniqueResult();
    String vertexId = resultMapping.getVertex().getVertexId();

    criteriaVertex.add(Restrictions.eq(Constants.Columns.VERTEX_ID, vertexId));
    VertexModel resultVertex = (VertexModel) criteriaVertex.uniqueResult();

    //resultVertex.getSourceEdgeSet().clear();
    //resultVertex.getDestinationEdgeSet().clear();

    session.delete(resultMapping);
    session.delete(resultVertex);

我尝试删除某些StackOverflow用户在其他问题上提到的实体,但这引发了这个异常: org.hibernate.ObjectDeletedException:已删除的对象将通过级联重新保存(从关联中删除已删除的对象)

如何删除(级联或模型父子关系),以便在删除顶点时,所有边缘事件都会被删除,但是当我删除边缘时,没有删除任何顶点?

编辑:由于没有回复,我只是想澄清问题很简单,我想建立一个父子关系,以便删除孩子不会删除父母。 (如果除此之外,我得到的功能是添加一个孩子将导致父母保存,这将更好)。 我该怎么做呢?我的注释错了吗?感谢

0 个答案:

没有答案