CrudRepository 中的 delete(Iterable<? extends T> itrbl) 和 JpaRepository 中的 deleteInBatch(Itera
Posted
技术标签:
【中文标题】CrudRepository 中的 delete(Iterable<? extends T> itrbl) 和 JpaRepository 中的 deleteInBatch(Iterable<T> itrbl) 有啥区别【英文标题】:What are differences between delete(Iterable<? extends T> itrbl) in CrudRepository and deleteInBatch(Iterable<T> itrbl) in JpaRepositoryCrudRepository 中的 delete(Iterable<? extends T> itrbl) 和 JpaRepository 中的 deleteInBatch(Iterable<T> itrbl) 有什么区别 【发布时间】:2015-04-01 00:14:53 【问题描述】:我在尝试删除具有外键的实体列表时遇到问题。 CrudRepository
中的删除方法可以很好地处理没有外键的表,但是当我尝试删除具有外键的实体列表时,它报告成功,但数据库中没有删除任何内容。 deleteInBatch()
在两者中都可以正常工作。
CrudRepository and deleteInBatch(Iterable<T> itrbl)
和 JpaRepository
中的方法 delete(Iterable<? extends T> itrbl)
有什么区别?
我已经通过this。
任何帮助将不胜感激
我的模型 SmsNotifyTemplate.java:
package com.viettel.pcrf.webconfig.model;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Anh Nguyen
*/
@Entity
@Table(name = "SMS_NOTIFY_TEMPLATE", catalog = "", schema = "VPCRF")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "SmsNotifyTemplate.findAll", query = "SELECT s FROM SmsNotifyTemplate s"),
@NamedQuery(name = "SmsNotifyTemplate.findBySmsNotifyTemplateId", query = "SELECT s FROM SmsNotifyTemplate s WHERE s.smsNotifyTemplateId = :smsNotifyTemplateId"),
@NamedQuery(name = "SmsNotifyTemplate.findByMessageTemplate", query = "SELECT s FROM SmsNotifyTemplate s WHERE s.messageTemplate = :messageTemplate"),
@NamedQuery(name = "SmsNotifyTemplate.findByComments", query = "SELECT s FROM SmsNotifyTemplate s WHERE s.comments = :comments"),
@NamedQuery(name = "SmsNotifyTemplate.findBySmsTemplateCode", query = "SELECT s FROM SmsNotifyTemplate s WHERE s.smsTemplateCode = :smsTemplateCode"))
public class SmsNotifyTemplate implements Serializable
public static enum COLUMNS
COMMENTS, LANGID, MESSAGETEMPLATE, SMSNOTIFYTEMPLATEID, SMSTEMPLATECODE
;
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "SMS_NOTIFY_TEMPLATE_ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "sms_notify_template_seq_gen")
@SequenceGenerator(name = "sms_notify_template_seq_gen", sequenceName = "SMS_NOTIFY_TEMPLATE_SEQ")
private Short smsNotifyTemplateId;
@Column(name = "MESSAGE_TEMPLATE", length = 480)
private String messageTemplate;
@Column(name = "COMMENTS", length = 200)
private String comments;
@Column(name = "SMS_TEMPLATE_CODE")
private Integer smsTemplateCode;
@JoinColumn(name = "LANG_ID", referencedColumnName = "LANG_ID", nullable = false)
@ManyToOne(optional = false)
private Lang langId;
public SmsNotifyTemplate()
public SmsNotifyTemplate(Short smsNotifyTemplateId)
this.smsNotifyTemplateId = smsNotifyTemplateId;
public Short getSmsNotifyTemplateId()
return smsNotifyTemplateId;
public void setSmsNotifyTemplateId(Short smsNotifyTemplateId)
this.smsNotifyTemplateId = smsNotifyTemplateId;
public String getMessageTemplate()
return messageTemplate;
public void setMessageTemplate(String messageTemplate)
this.messageTemplate = messageTemplate;
public String getComments()
return comments;
public void setComments(String comments)
this.comments = comments;
public Integer getSmsTemplateCode()
return smsTemplateCode;
public void setSmsTemplateCode(Integer smsTemplateCode)
this.smsTemplateCode = smsTemplateCode;
public Lang getLangId()
return langId;
public void setLangId(Lang langId)
this.langId = langId;
@Override
public int hashCode()
int hash = 0;
hash += (smsNotifyTemplateId != null ? smsNotifyTemplateId.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 SmsNotifyTemplate))
return false;
SmsNotifyTemplate other = (SmsNotifyTemplate) object;
return !((this.smsNotifyTemplateId == null && other.smsNotifyTemplateId != null) || (this.smsNotifyTemplateId != null && !this.smsNotifyTemplateId.equals(other.smsNotifyTemplateId)));
@Override
public String toString()
return "com.viettel.pcrf.model.SmsNotifyTemplate[ smsNotifyTemplateId=" + smsNotifyTemplateId + " ]";
我有一个映射器来将模型映射到一个普通的类:
SmsTemplateMapper.java:
package com.viettel.pcrf.webconfig.mapper;
import com.viettel.fw.common.util.mapper.BaseMapper;
import com.viettel.pcrf.webconfig.dto.SmsTemplateDTO;
import com.viettel.pcrf.webconfig.model.SmsNotifyTemplate;
public class SmsTemplateMapper extends BaseMapper<SmsNotifyTemplate, SmsTemplateDTO>
@Override
public SmsTemplateDTO toDtoBean(SmsNotifyTemplate model)
SmsTemplateDTO obj = null;
if (model != null)
obj = new SmsTemplateDTO();
obj.setComments(model.getComments());
obj.setMessageTemplate(model.getMessageTemplate());
obj.setSmsNotifyTemplateId(model.getSmsNotifyTemplateId());
obj.setSmsTemplateCode(model.getSmsTemplateCode());
obj.setLangId(model.getLangId());
return obj;
@Override
public SmsNotifyTemplate toPersistenceBean(SmsTemplateDTO dtoBean)
SmsNotifyTemplate obj = null;
if (dtoBean != null)
obj = new SmsNotifyTemplate();
obj.setComments(dtoBean.getComments());
obj.setMessageTemplate(dtoBean.getMessageTemplate());
obj.setSmsNotifyTemplateId(dtoBean.getSmsNotifyTemplateId());
obj.setSmsTemplateCode(dtoBean.getSmsTemplateCode());
obj.setLangId(dtoBean.getLangId());
System.out.println(obj.getLangId().getNationality());
return obj;
SmsTemplateDTO.java:
package com.viettel.pcrf.webconfig.dto;
import com.viettel.fw.dto.BaseDTO;
import com.viettel.pcrf.webconfig.model.Lang;
import java.io.Serializable;
public class SmsTemplateDTO extends BaseDTO implements Serializable
public String getKeySet()
return keySet;
private String comments;
private String messageTemplate;
private Short smsNotifyTemplateId;
private Integer smsTemplateCode;
private Lang langId;
public String getComments()
return this.comments;
public void setComments(String comments)
this.comments = comments;
public String getMessageTemplate()
return this.messageTemplate;
public void setMessageTemplate(String messageTemplate)
this.messageTemplate = messageTemplate;
public Short getSmsNotifyTemplateId()
return this.smsNotifyTemplateId;
public void setSmsNotifyTemplateId(Short smsNotifyTemplateId)
this.smsNotifyTemplateId = smsNotifyTemplateId;
public Integer getSmsTemplateCode()
return this.smsTemplateCode;
public void setSmsTemplateCode(Integer smsTemplateCode)
this.smsTemplateCode = smsTemplateCode;
public Lang getLangId()
return langId;
public void setLangId(Lang langId)
this.langId = langId;
SmsTemplateRepo.java:
package com.viettel.pcrf.webconfig.repo;
import com.viettel.fw.persistence.BaseRepository;
import java.util.List;
import com.viettel.pcrf.webconfig.model.SmsNotifyTemplate;
public interface SmsTemplateRepo extends BaseRepository<SmsNotifyTemplate>, SmsTemplateRepoCustom
public List<SmsNotifyTemplate> findByComments(String comments);
public List<SmsNotifyTemplate> findByMessageTemplate(String messageTemplate);
public List<SmsNotifyTemplate> findBySmsNotifyTemplateId(Short smsNotifyTemplateId);
public List<SmsNotifyTemplate> findBySmsTemplateCode(Integer smsTemplateCode);
BaseRepository 扩展了 JpaRepository。
删除方法将在该类的 deleteSmsNotifyTemplates 方法中:
SmsTemplateServiceImpl.java:
package com.viettel.pcrf.webconfig.service;
import com.viettel.fw.common.util.extjs.FilterRequest;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.pcrf.webconfig.repo.SmsTemplateRepo;
import com.viettel.pcrf.webconfig.mapper.SmsTemplateMapper;
import com.viettel.pcrf.webconfig.dto.SmsTemplateDTO;
import com.viettel.pcrf.webconfig.model.SmsNotifyTemplate;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
*
* @author Anh Nguyen
*/
@Service
public class SmsTemplateServiceImpl extends BaseServiceImpl implements SmsTemplateService
private final SmsTemplateMapper mapper = new SmsTemplateMapper();
@Autowired
private SmsTemplateRepo repository;
public Logger logger = Logger.getLogger(SmsTemplateService.class);
@Override
public BaseMessage deleteSmsNotifyTemplates(List<SmsTemplateDTO> smsNotifyTemplateDTOs) throws Exception
BaseMessage baseMessage = new BaseMessage();
repository.delete(mapper.toPersistenceBean(smsNotifyTemplateDTOs));
baseMessage.setSuccess(true);
baseMessage.setOutputObject(smsNotifyTemplateDTOs);
return baseMessage;
控制器:
SmsTemplateCtrl.java:
package com.viettel.pcrf.webconfig.controller;
import com.viettel.fw.Exception.LogicException;
import com.viettel.fw.common.util.extjs.FilterRequest;
import com.viettel.fw.web.controller.BaseController;
import com.viettel.pcrf.webconfig.dto.LangDTO;
import com.viettel.pcrf.webconfig.dto.SmsTemplateDTO;
import com.viettel.pcrf.webconfig.model.Lang;
import com.viettel.pcrf.webconfig.service.LangService;
import com.viettel.pcrf.webconfig.service.SmsTemplateService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
*
* @author Anh Nguyen
*/
@Component("smsNotifyTemplateController")
@Scope("view")
public class SmsTemplateCtrl extends BaseController implements Serializable
private List<SmsTemplateDTO> listSmsNotifyTemplate;
private SmsTemplateDTO smsNotifyTemplate;
private List<SmsTemplateDTO> selectedSmsNotifyTemplates;
private List<LangDTO> listLang;
@Autowired
private SmsTemplateService smsNotifyTemplateService;
@Autowired
private LangService langService;
public List<SmsTemplateDTO> getListSmsNotifyTemplate()
return listSmsNotifyTemplate;
public void setListSmsNotifyTemplate(List<SmsTemplateDTO> listSmsNotifyTemplate)
this.listSmsNotifyTemplate = listSmsNotifyTemplate;
public SmsTemplateDTO getSmsNotifyTemplate()
return smsNotifyTemplate;
public void setSmsNotifyTemplate(SmsTemplateDTO smsNotifyTemplate)
this.smsNotifyTemplate = smsNotifyTemplate;
public List<SmsTemplateDTO> getSelectedSmsNotifyTemplates()
return selectedSmsNotifyTemplates;
public void setSelectedSmsNotifyTemplates(List<SmsTemplateDTO> selectedSmsNotifyTemplates)
this.selectedSmsNotifyTemplates = selectedSmsNotifyTemplates;
public List<LangDTO> getListLang()
return listLang;
public void setListLang(List<LangDTO> listLang)
this.listLang = listLang;
/**
* Khoi Tao Cac doi tuong de load len view
*/
@PostConstruct
public void init()
listSmsNotifyTemplate = smsNotifyTemplateService.findAllSort();
listLang = langService.findAllSort();
formStatus = getFormStatus();
/**
* Chuan bi cho thao tac delete
*/
public void delete()
try
if (selectedSmsNotifyTemplates == null || selectedSmsNotifyTemplates.isEmpty())
reportError("msgInfo", "Choose one row!");
else
smsNotifyTemplateService.deleteSmsNotifyTemplates(selectedSmsNotifyTemplates);
reportSuccess("msgInfo", "common.msg.success.delete");
reset();
updateController();
catch (LogicException logicE)
reportError("msgInfo", logicE);
catch (Exception exception)
reportError("msgInfo", exception.getMessage());
/**
* Kiem tra SmsNotifyTemplateId ton tai trong bang SMS_NOTIFY_TEMPLATE
*
* @param smsNotifyTemplates
* @return
*/
public boolean SmsNotifyTemplateIdExistedInSmsNotifyTemplate(List<SmsTemplateDTO> smsNotifyTemplates)
List<FilterRequest> listReq = new ArrayList<>();
for (SmsTemplateDTO s : smsNotifyTemplates)
listReq.add(new FilterRequest("LANGID", s.getLangId()));
List<SmsTemplateDTO> list = smsNotifyTemplateService.findAll(listReq);
return !list.isEmpty();
/**
* Kiem tra SmsNotifyTemplateCode ton tai trong bang LANG
*
* @param smsTemplateCode
* @param smsNotifyTemplateId
* @return
*/
public boolean SmsTemplateCodeExisted(Integer smsTemplateCode, Short smsNotifyTemplateId)
List<FilterRequest> listReq = new ArrayList<>();
listReq.add(new FilterRequest("SMSTEMPLATECODE", smsTemplateCode));
List<SmsTemplateDTO> list = smsNotifyTemplateService.findAll(listReq);
if (list.isEmpty())
return false;
if (list.size() > 1)
return true;
else
return !list.get(0).getSmsNotifyTemplateId().equals(smsNotifyTemplateId);
还有 xhtml 页面。我正在使用 primefaces 框架。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="../../templates/layoutTemplate.xhtml" >
<ui:define name="title">SMS Notify Template Configuration</ui:define>
<ui:define name="featureName">SMS Notify Template Configuration</ui:define>
<ui:define name="content">
<h:form id="frmSmsNotifyTemplate">
<p:dataTable var="tabSmsNotifyTemplate"
id="smsNotifyTemplateList"
value="#smsNotifyTemplateController.listSmsNotifyTemplate"
selection="#smsNotifyTemplateController.selectedSmsNotifyTemplates"
rowsPerPageTemplate="5,10,15,20,50"
paginatorPosition="bottom"
paginator="true"
rows="10"
paginatorAlwaysVisible="false"
sortMode="single"
sortBy="#tabSmsNotifyTemplate.smsNotifyTemplateId"
rowKey="#tabSmsNotifyTemplate.smsNotifyTemplateId" >
<p:column selectionMode="multiple" style="width:16px;text-align:center" />
<p:ajax event="toggleSelect" update="@([id$=btnEdit]) @([id$=btnDelete])" />
<p:ajax event="rowSelect" update="@([id$=btnEdit]) @([id$=btnDelete])" />
<p:ajax event="rowSelectCheckbox" update="@([id$=btnEdit]) @([id$=btnDelete])" />
<p:ajax event="rowUnselectCheckbox" update="@([id$=btnEdit]) @([id$=btnDelete])" />
<p:column headerText="ID" style="width: 100px;">
<h:outputText value="#tabSmsNotifyTemplate.smsNotifyTemplateId" />
</p:column>
<p:column headerText="Message Template" style="width: 100px;" sortBy="#tabSmsNotifyTemplate.messageTemplate">
<h:outputText value="#tabSmsNotifyTemplate.messageTemplate" />
</p:column>
<p:column headerText="SMS Template Code" sortBy="#tabSmsNotifyTemplate.smsTemplateCode">
<h:outputText value="#tabSmsNotifyTemplate.smsTemplateCode" />
</p:column>
<p:column headerText="Language" sortBy="#tabSmsNotifyTemplate.langId.nationality">
<h:outputText value="#tabSmsNotifyTemplate.langId.nationality" />
</p:column>
<p:column headerText="Comments" sortBy="#tabSmsNotifyTemplate.comments">
<h:outputText value="#tabSmsNotifyTemplate.comments" />
</p:column>
<f:facet name="footer">
<div align="left">
<span class="vt-button">
<p:commandLink
action="#smsNotifyTemplateController.prepareInsert()"
process="smsNotifyTemplateList"
update="@form"
resetValues="true"
style="margin-right:30px;border: none">
<p:graphicImage style="width:10px;height:10px;"
value="/resources/themes/images/icon-add.png"/>
<span class="vt-button-text">
<h:outputText value="#lang['common.button.add']"/>
</span>
<f:setPropertyActionListener
target="#smsNotifyTemplateController.formStatus"
value="#vpcrfConst.BTN_ADD"/>
</p:commandLink>
<p:commandLink
id="btnEdit"
action="#smsNotifyTemplateController.prepareEdit()"
process="smsNotifyTemplateList"
update="@form"
disabled="#smsNotifyTemplateController.selectedSmsNotifyTemplates.size()>1 or smsNotifyTemplateController.selectedSmsNotifyTemplates==null or smsNotifyTemplateController.selectedSmsNotifyTemplates.size()==0"
resetValues="true"
style="margin-right:30px;border: none">
<p:graphicImage style="width:10px;height:10px;"
value="/resources/themes/images/icon-edit.png"/>
<span class="vt-button-text">
<h:outputText value="#lang['common.button.edit']"/>
</span>
<f:setPropertyActionListener
target="#smsNotifyTemplateController.formStatus"
value="#vpcrfConst.BTN_EDIT"/>
</p:commandLink>
<p:commandLink
id="btnDelete"
action="#smsNotifyTemplateController.delete()"
immediate="true"
update="@form"
disabled="#smsNotifyTemplateController.selectedSmsNotifyTemplates.size()==0 or smsNotifyTemplateController.selectedSmsNotifyTemplates==null"
resetValues="true"
style="margin-right:30px;border: none">
<p:graphicImage style="width:10px;height:10px;"
value="/resources/themes/images/icon-delete.png"/>
<span class="vt-button-text">
<h:outputText value="#lang['common.button.delete']"/>
</span>
<p:confirm header="Delete" message="Are you sure? (Ok/Cancel)" icon="ui-icon-alert" />
</p:commandLink>
</span>
</div>
</f:facet>
</p:dataTable>
<p:growl id="testMsg" showSummary="false" showDetail="true" autoUpdate="true" sticky="true" />
<p:focus context="editPanel"/>
<p:fieldset legend="SMS Notify Template Detail" rendered="#smsNotifyTemplateController.smsNotifyTemplate!=null">
<h:panelGrid id="editPanel"
columnClasses="vocs-120, vocs-300"
columns="2" rendered="#smsNotifyTemplateController.smsNotifyTemplate!=null">
<p:outputLabel for="smsID" value="ID" />
<p:inputText id="smsID"
value="#smsNotifyTemplateController.smsNotifyTemplate.smsNotifyTemplateId"
required="true"
maxlength="15"
disabled="true"
style="min-width: 300px;"/>
<p:outputLabel for="messTemplate" value="Message Template" />
<p:inputText id="messTemplate"
value="#smsNotifyTemplateController.smsNotifyTemplate.messageTemplate"
required="true"
maxlength="60"
style="min-width: 300px;"/>
<p:outputLabel for="langId" value="SMS Notify Template" />
<p:selectOneMenu id="langId"
required="true"
value="#smsNotifyTemplateController.smsNotifyTemplate.langId.langId"
style="width: 306px;">
<f:selectItem itemLabel="Select Language"
itemDisabled="true"
noSelectionOption="true"/>
<f:selectItems value="#smsNotifyTemplateController.listLang"
var="l"
itemLabelEscaped="true"
itemValue="#l.langId"
itemLabel="#l.nationality" />
</p:selectOneMenu>
<p:outputLabel for="templateCode" value="Template Code" />
<p:inputTextarea id="templateCode"
value="#smsNotifyTemplateController.smsNotifyTemplate.smsTemplateCode"
required="true"
maxlength="10"
style="min-width: 300px;"/>
<p:outputLabel for="comments" value="Comments" />
<p:inputTextarea id="comments"
value="#smsNotifyTemplateController.smsNotifyTemplate.comments"
required="false"
maxlength="10"
style="min-width: 300px;"/>
<div />
<h:panelGroup>
<p:commandButton
value="OK"
process="editPanel"
rendered="#smsNotifyTemplateController.formStatus==vpcrfConst.BTN_ADD"
action="#smsNotifyTemplateController.insert()"
update="smsNotifyTemplateList,editPanel,@form" />
<p:commandButton rendered="#smsNotifyTemplateController.formStatus==vpcrfConst.BTN_ADD"
value="#lang['common.button.reset']"
immediate="true">
<p:ajax update="smsID,messTemplate,langId,templateCode,comments" resetValues="true" />
</p:commandButton>
<p:commandButton
value="OK"
rendered="#smsNotifyTemplateController.formStatus==vpcrfConst.BTN_EDIT"
action="#smsNotifyTemplateController.update()"
update="smsNotifyTemplateList,editPanel,@form" />
<p:commandButton rendered="#smsNotifyTemplateController.formStatus==vpcrfConst.BTN_EDIT"
value="#lang['common.button.reset']"
immediate="true"
action="#smsNotifyTemplateController.clearInput()"
update="smsID,messTemplate,langId,templateCode,comments"
resetValues="true"/>
<p:commandButton
value="#lang['common.button.cancel']"
action="#smsNotifyTemplateController.reset()"
immediate="true"
update="@form"/>
</h:panelGroup>
</h:panelGrid>
</p:fieldset>
</h:form>
</ui:define>
</ui:composition>
</html>
【问题讨论】:
【参考方案1】:文档解释了差异。 deleteInBatch()
执行以下操作:
批量删除给定的实体,这意味着它将创建一个查询。假设我们将在调用后清除 EntityManager。
而delete()
执行以下操作:
删除给定的实体。
所以,第一个将执行删除 JPQL 查询,如
delete from SomeEntity e where e.id in :ids
而第二个将遍历实体并调用
entityManager.remove(entity)
无论您的实体是否有外键,两者都应该有效。第二个将应用级联,而第一个不会。在不了解您的代码的情况下,不可能说出您遇到此问题的原因。
【讨论】:
你好。我更新了有问题的代码。你能帮助澄清这个问题。谢谢以上是关于CrudRepository 中的 delete(Iterable<? extends T> itrbl) 和 JpaRepository 中的 deleteInBatch(Itera的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Data JPA CRUDRepository 中添加缓存功能
CRUDRepository 中的 Update 或 saveorUpdate
如何修复CrudRepository.save(java.lang.Object)是springboot中的无法访问方法?
Spring data : CrudRepository 的保存方法和更新
如何解决 CrudRepository<FinancialTransaction,String> 类型中的方法 save(S) 不适用于参数(付款)