JPA снимает ограничения во время выполнения - PullRequest
0 голосов
/ 14 декабря 2009

Я удаляю сущности из таблицы с отношением один ко многим к одной и той же сущности (представляющей иерархию узлов). Если я сделаю отношение 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 + "]";
    }
}

Ответы [ 2 ]

0 голосов
/ 17 декабря 2009

Я закончил делать специальный случай в 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;
}
0 голосов
/ 14 декабря 2009

Если вы используете Hibernate, вы можете использовать его поддержку пакетной обработки для эффективного удаления многих строк в таблице. По сути, запрос переводится с HQL на SQL и работает непосредственно с базой данных. Однако у этого подхода есть ограничения. Например, состояние в памяти не будет обновлено, если вы держите ссылки на любой из затронутых объектов.

Я не знаю, поддерживает ли сама JPA пакетную обработку. Возможно нет. Но если вы ожидаете, что это повлияет на множество строк (сотни или тысячи), то это один из тех случаев, когда ORM в любом случае не совсем подходящий инструмент для работы. Возможно, имеет смысл сделать это в прямом SQL или хранимой процедуре. В любом случае, вы можете изолировать код внутри объекта доступа к данным, так что бизнес-логике высокого уровня не нужно заботиться о том, как реализована операция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...