Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA在运行时删除约束_Java_Jpa - Fatal编程技术网

Java JPA在运行时删除约束

Java JPA在运行时删除约束,java,jpa,Java,Jpa,我正在从表中删除实体,该表与表示节点层次结构的同一实体具有一对多关系。如果我将xincoCoreNodeId关系设置为级联,那么所有这些都可以工作,但我不希望在实际应用程序中这样做 我不想删除一个叶子删除它的父对象。有没有一种方法可以在运行时修改此关系或禁用约束,这样我就可以删除整个表内容,而不会收到约束投诉 package com.bluecubs.xinco.core.server.persistence; import com.bluecubs.xinco.core.server

我正在从表中删除实体,该表与表示节点层次结构的同一实体具有一对多关系。如果我将xincoCoreNodeId关系设置为级联,那么所有这些都可以工作,但我不希望在实际应用程序中这样做

我不想删除一个叶子删除它的父对象。有没有一种方法可以在运行时修改此关系或禁用约束,这样我就可以删除整个表内容,而不会收到约束投诉

    package com.bluecubs.xinco.core.server.persistence;

import com.bluecubs.xinco.core.server.AuditedEntityListener;
import com.bluecubs.xinco.core.server.XincoAuditedObject;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.persistence.annotations.PrivateOwned;

/**
 *
 * @author Javier A. Ortiz Bultrón <javier.ortiz.78@gmail.com>
 */
@Entity
@Table(name = "xinco_core_node")
@EntityListeners(AuditedEntityListener.class)
@NamedQueries({
    @NamedQuery(name = "XincoCoreNode.findAll", query = "SELECT x FROM XincoCoreNode x"),
    @NamedQuery(name = "XincoCoreNode.findById", query = "SELECT x FROM XincoCoreNode x WHERE x.id = :id"),
    @NamedQuery(name = "XincoCoreNode.findByDesignation", query = "SELECT x FROM XincoCoreNode x WHERE x.designation = :designation"),
    @NamedQuery(name = "XincoCoreNode.findByStatusNumber", query = "SELECT x FROM XincoCoreNode x WHERE x.statusNumber = :statusNumber")})
public class XincoCoreNode extends XincoAuditedObject implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id", nullable = false)
    private Integer id;
    @Basic(optional = false)
    @Column(name = "designation", nullable = false, length = 255)
    private String designation;
    @Basic(optional = false)
    @Column(name = "status_number", nullable = false)
    private int statusNumber;
    @JoinColumn(name = "xinco_core_language_id", referencedColumnName = "id", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private XincoCoreLanguage xincoCoreLanguageId;
    @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "xincoCoreNodeId", fetch = FetchType.LAZY)
    private List<XincoCoreNode> xincoCoreNodeList;
    @JoinColumn(name = "xinco_core_node_id", referencedColumnName = "id")
    @PrivateOwned
    @ManyToOne(fetch = FetchType.LAZY)
    private XincoCoreNode xincoCoreNodeId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "xincoCoreNodeId", fetch = FetchType.LAZY)
    private List<XincoCoreAce> xincoCoreAceList;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "xincoCoreNodeId", fetch = FetchType.LAZY)
    private List<XincoCoreData> xincoCoreDataList;

    public XincoCoreNode() {
    }

    public XincoCoreNode(Integer id) {
        this.id = id;
    }

    public XincoCoreNode(Integer id, String designation, int statusNumber) {
        this.id = id;
        this.designation = designation;
        this.statusNumber = statusNumber;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public int getStatusNumber() {
        return statusNumber;
    }

    public void setStatusNumber(int statusNumber) {
        this.statusNumber = statusNumber;
    }

    public XincoCoreLanguage getXincoCoreLanguageId() {
        return xincoCoreLanguageId;
    }

    public void setXincoCoreLanguageId(XincoCoreLanguage xincoCoreLanguageId) {
        this.xincoCoreLanguageId = xincoCoreLanguageId;
    }

    public List<XincoCoreNode> getXincoCoreNodeList() {
        return xincoCoreNodeList;
    }

    public void setXincoCoreNodeList(List<XincoCoreNode> xincoCoreNodeList) {
        this.xincoCoreNodeList = xincoCoreNodeList;
    }

    public XincoCoreNode getXincoCoreNodeId() {
        return xincoCoreNodeId;
    }

    public void setXincoCoreNodeId(XincoCoreNode xincoCoreNodeId) {
        this.xincoCoreNodeId = xincoCoreNodeId;
    }

    public List<XincoCoreAce> getXincoCoreAceList() {
        return xincoCoreAceList;
    }

    public void setXincoCoreAceList(List<XincoCoreAce> xincoCoreAceList) {
        this.xincoCoreAceList = xincoCoreAceList;
    }

    public List<XincoCoreData> getXincoCoreDataList() {
        return xincoCoreDataList;
    }

    public void setXincoCoreDataList(List<XincoCoreData> xincoCoreDataList) {
        this.xincoCoreDataList = xincoCoreDataList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof XincoCoreNode)) {
            return false;
        }
        XincoCoreNode other = (XincoCoreNode) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.bluecubs.xinco.core.server.persistence.XincoCoreNode[id=" + id + "]";
    }
}

如果您使用的是Hibernate,那么可以使用它对的支持高效地删除表中的许多行。基本上,查询从HQL转换为SQL,并直接针对数据库运行。不过,这种方法也有局限性。例如,如果您持有对任何受影响对象的引用,则不会更新内存中的状态


我不知道JPA本身是否支持批处理。可能不会。但是,如果您希望影响数百行或数千行,那么无论如何,ORM并不是这项工作的正确工具。在纯SQL或存储过程中执行此操作可能更有意义。无论哪种方式,您都可以隔离数据访问对象中的代码,这样高级业务逻辑就不必关心操作是如何实现的。

我最后用Java做了一个特例来处理这个问题

@Override
public void clearTable() {
    try {
        /**
         * All nodes are linked except the root. So we need to start deleting the leaves first.
         */
        while (new XincoCoreNodeJpaController().findXincoCoreNodeEntities().size() > 0) {
            for (com.bluecubs.xinco.core.server.persistence.XincoCoreNode xcn : getLeaves()) {
                new XincoCoreNodeJpaController().destroy(xcn.getId());
            }
        }
    } catch (XincoException ex) {
        Logger.getLogger(XincoCoreNodeServer.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private Vector<com.bluecubs.xinco.core.server.persistence.XincoCoreNode> getLeaves() throws XincoException {
    Vector<com.bluecubs.xinco.core.server.persistence.XincoCoreNode> leaves =
            new Vector<com.bluecubs.xinco.core.server.persistence.XincoCoreNode>();
    result = XincoDBManager.protectedCreatedQuery("select x from XincoCoreNode x " +
            "where x.id not in (select y.xincoCoreNodeId.id from XincoCoreNode y " +
            "where y.xincoCoreNodeId is not null)",null,true);
    if (result.size() == 0) {
        //Check if the root is there
        for (Object o : new XincoCoreNodeJpaController().findXincoCoreNodeEntities()) {
            leaves.add((com.bluecubs.xinco.core.server.persistence.XincoCoreNode) o);
        }
    }
    for (Object o : result) {
        leaves.add((com.bluecubs.xinco.core.server.persistence.XincoCoreNode) o);
    }
    return leaves;
}

如果不想将删除从leaf级联到父级,请不要像这样级联。事实上,我并不真正明白这个问题。在哪种情况下会出现约束冲突?我使用Eclipselink是因为我在Hibernate中发现了一些问题。好的,所以假设Eclipselink不支持本机批处理,我建议使用SQL选项。我试图避免使用SQL,因为目标数据库可以是JPA实现支持的任何东西。我将此视为例外,并以特殊的方式处理它。请参阅下面的工作代码。JpaController类是由Netbeans工具从main post中的实体类生成的。