【问题标题】:Setting up a hibernate model using annotations to allow cascaded deletes in hibernate使用注释设置休眠模型以允许休眠中的级联删除
【发布时间】:2014-03-17 10:25:27
【问题描述】:

我有两个表,doc_table 和 code_table 是一对多关系。我定义了一个服务来删除 doc_table 中的条目,我想要的是应该同时删除 code_table 中的相应条目(级联删除)。这是服务

    public void deleteDoctable(String anumber) throws DataBaseAccessException {
    Session session = null;
    try {
    session = HibernateUtils.beginTransaction("emscribedx");
    Query q = session.createQuery("delete Doc_table  where docnumber = :docnum");
    q.setParameter("docnum", anumber);
    q.executeUpdate();
    session.getTransaction().commit();
    }  catch (HibernateException e_) {
        e_.printStackTrace();
    }
    finally {
        try {
            HibernateUtils.closeSessions();
        } catch (Exception e) {
            NTEVENT_LOG.error("Problem closing hibernate session!!!");
        }
    }

}

当我执行此服务时,它会删除 Doc_table 中的条目,但不会将删除级联到 Code_table。下面是我正在使用的 Doc_table 的注释模型。请注意,我用 cascadeType.All 注释了一对多关系。但我仍然没有得到预期的级联删除。
关于发生了什么的任何想法? 导入 java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
 import javax.persistence.Table;

import org.hibernate.lucene.Text;

import com.artificialmed.domain.code.model.Code_table;
@Entity
@Table (name="doc_table", catalog="emscribedx")
public class Doc_table {
private Long _id; 
private String _acct;
private String _message;
private String _document;
private String _doctype;
private String _review_date;
private String _createDate;
private int _dummyflag;
private String _reviewer;
private String _ProcedureDocLast;
private String _ProcedureDocFirst;
private String _ProcedureDocMiddle;
private String _ProcedureDate;
private String _ProcedureDocNumber;
private String _Note;
private String _dbcreate_date;
private String _docnumber;
private String _selectedcodes ;
private int _viewed ;
private int _postsubmit ;
private List <Code_table> _code_table;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column (name = "id")
public Long getId() {
    return _id;
}
public void setId(Long id_) {
    _id = id_;
}

@Column (name = "acct")
public String getAcct() {
    return _acct;
}
public void setAcct(String acct_) {
    _acct = acct_;
}

@Column (name = "message")
public String getMessage() {
    return _message;
}
public void setMessage(String message_) {
    _message = message_;
}


@Column (name = "document")
public String getDocument() {
    return _document;
}
public void setDocument(String document_) {
    _document = document_;
}

@Column (name = "doctype")
public String getDoctype() {
    return _doctype;
}
public void setDoctype(String doctype_) {
    _doctype = doctype_;
}

@Column (name = "review_date")
public String getReview_date() {
    return _review_date;
}
public void setReview_date(String reviewDate_) {
    _review_date = reviewDate_;
}

@Column (name = "create_date")
public String getCreateDate() {
    return _createDate;
}
public void setCreateDate(String createDate_) {
    _createDate = createDate_;
}

@Column (name = "dummyflag")
public int getDummyflag() {
    return _dummyflag;
}
public void setDummyflag(int dummyflag_) {
    _dummyflag = dummyflag_;
}

@Column (name = "reviewer")
public String getReviewer() {
    return _reviewer;
}
public void setReviewer(String reviewer_) {
    _reviewer = reviewer_;
}

@Column (name = "ProcedureDocLast")
public String getProcedureDocLast() {
    return _ProcedureDocLast;
}
public void setProcedureDocLast(String procedureDocLast_) {
    _ProcedureDocLast = procedureDocLast_;
}

@Column (name = "ProcedureDocFirst")
public String getProcedureDocFirst() {
    return _ProcedureDocFirst;
}
public void setProcedureDocFirst(String procedureDocFirst_) {
    _ProcedureDocFirst = procedureDocFirst_;
}

@Column (name = "ProcedureDocMiddle")
public String getProcedureDocMiddle() {
    return _ProcedureDocMiddle;
}
public void setProcedureDocMiddle(String procedureDocMiddle_) {
    _ProcedureDocMiddle = procedureDocMiddle_;
}

@Column (name = "ProcedureDate")
public String getProcedureDate() {
    return _ProcedureDate;
}
public void setProcedureDate(String procedureDate_) {
    _ProcedureDate = procedureDate_;
}

@Column (name = "ProcedureDocNumber")
public String getProcedureDocNumber() {
    return _ProcedureDocNumber;
}
public void setProcedureDocNumber(String procedureDocNumber_) {
    _ProcedureDocNumber = procedureDocNumber_;
}

@Column (name = "Note")
public String getNote() {
    return _Note;
}
public void setNote(String note_) {
    _Note = note_;
}

@Column (name = "dbcreate_date")
public String getDbcreate_date() {
    return _dbcreate_date;
}
public void setDbcreate_date(String dbcreateDate_) {
    _dbcreate_date = dbcreateDate_;
}

@Column (name = "docnumber")
public String getDocnumber() {
    return _docnumber;
}
public void setDocnumber(String docnumber_) {
    _docnumber = docnumber_;
}


@Column (name = "selectedcodes")
public String getSelectedcodes() {
    return _selectedcodes;
}
public void setSelectedcodes(String codes_) {
    _selectedcodes = codes_;
}

@Column (name = "viewed")
public int getViewed() {
    return _viewed;
}
public void setViewed(int viewed_) {
    _viewed = viewed_;
}

@Column (name = "postsubmit")
public int getPostsubmit() {
    return _postsubmit;
}
public void setPostsubmit(int postsubmit_) {
    _postsubmit = postsubmit_;
}


@OneToMany (mappedBy = "doc_table", targetEntity = Code_table.class, cascade = CascadeType.ALL)
public List <Code_table> getCode_table() {
    return _code_table;
}
public void setCode_table(List <Code_table> codeTable_) {
    _code_table = codeTable_;
}

【问题讨论】:

    标签: java hibernate cascading-deletes


    【解决方案1】:

    当您在会话上调用相应的方法时会应用级联。不是在执行 DML 查询时。所以,假设 docNumber 是实体的 ID,你只需要

    Doc_table d = (Doc_table) session.get(Doc_table.class, docNumber);
    session.delete(d);
    

    请注意,您应该遵守标准的 Java 命名约定,并避免名称中出现杂音。将表命名为 XXX_table 是没有用的。为 entity XXX_table 命名是没有用的、令人困惑的,并且不尊重命名约定。文档实体应命名为Document

    【讨论】:

      【解决方案2】:

      当您对查询进行任意更改时,传递持久性不会做任何事情。一般来说,除非您正在执行批量操作并且有性能问题,否则最好避免使用查询进行更改并使用实际的 hibernate/jpa API。它与缓存混淆,破坏会话状态,通常只是难以破译问题的秘诀。

        session = HibernateUtils.beginTransaction("emscribedx");
        Query q = session.createQuery("from Doc_table  where docnumber = :docnum");
        q.setParameter("docnum", anumber);
        List<Doc_table> results = (List<Doc_table>)q.list();
        for (Doc_table result: results) {
          session.delete(result);
        }
        session.getTransaction().commit();
      

      是的,这涉及一个额外的查询。欢迎冬眠!漂亮的 API 和神奇的抽象不是免费的。如果您有实际 ID,您可以使用 Session#load 来避免这种情况,以创建一个没有实际选择语句的惰性代理。

      【讨论】:

      • Session.get() 将进行选择查询。 Session.load() 是不加载任何东西的那个(是的,好命名!)。
      • 哎呀,tx 抓住了那个
      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 2011-02-02
      • 2011-12-01
      • 2011-04-12
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 2011-04-17
      相关资源
      最近更新 更多