我正在使用现有数据库表(在Oracle中)使用jpa开发代码,其中我遇到了删除实体子项的子项的问题。
让我给你一些片段:
祖父母实体:
package com.blah.blah.jpa;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "BD_SETUP")
public class BDSetup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "BD_SETUP_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "BD_SETUP_SEQ", sequenceName = "BD_SETUP_SEQ", allocationSize = 1)
@Column(name = "ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "BD_SECURITY_ID", insertable = true, updatable = false)
private BDSecurity bdSecurity;
@Column(name = "IS_ENABLED")
private String isEnabled;
@Column(name = "IS_FULL_LOAD")
private String isFullLoad;
@Column(name = "LAST_RUN_BEGIN")
private Timestamp lastRunBegin;
@Column(name = "LAST_RUN_END")
private Timestamp lastRunEnd;
@Column(name = "NEXT_RUN_BEGIN")
private Timestamp nextRunBegin;
@Column(name = "NAME")
private String name;
@Column(name = "COMMENTS")
private String comments;
@OneToMany(mappedBy = "bdSetup", fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<BDExtractSetup> bdExtractSetups = new HashSet<BDExtractSetup>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BDSecurity getBdSecurity() {
return bdSecurity;
}
public void setBdSecurity(BDSecurity bdSecurity) {
this.bdSecurity = bdSecurity;
}
public String getIsEnabled() {
return isEnabled;
}
public void setIsEnabled(String isEnabled) {
this.isEnabled = isEnabled;
}
public String getIsFullLoad() {
return isFullLoad;
}
public void setIsFullLoad(String isFullLoad) {
this.isFullLoad = isFullLoad;
}
public Timestamp getLastRunBegin() {
return lastRunBegin;
}
public void setLastRunBegin(Timestamp lastRunBegin) {
this.lastRunBegin = lastRunBegin;
}
public Timestamp getLastRunEnd() {
return lastRunEnd;
}
public void setLastRunEnd(Timestamp lastRunEnd) {
this.lastRunEnd = lastRunEnd;
}
public Timestamp getNextRunBegin() {
return nextRunBegin;
}
public void setNextRunBegin(Timestamp nextRunBegin) {
this.nextRunBegin = nextRunBegin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Set<BDExtractSetup> getBdExtractSetups() {
return bdExtractSetups;
}
public void setBdExtractSetups(Set<BDExtractSetup> bdExtractSetups) {
this.bdExtractSetups = bdExtractSetups;
}
@Override
public String toString() {
return "BDSetup [id=" + id + ", bdSecurity=" + bdSecurity
+ ", isEnabled=" + isEnabled + ", isFullLoad=" + isFullLoad
+ ", lastRunBegin=" + lastRunBegin + ", lastRunEnd="
+ lastRunEnd + ", nextRunBegin=" + nextRunBegin + ", name="
+ name + ", comments=" + comments + "]";
}
}
Son Entity (带有额外列的映射表):
package com.blah.blah.jpa;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "BD_EXTRACT_SETUP")
public class BDExtractSetup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "BD_EXTRACT_SETUP_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "BD_EXTRACT_SETUP_SEQ", sequenceName = "BD_EXTRACT_SETUP_SEQ", allocationSize = 1)
private Long id;
// bi-directional many-to-one association to BDSetup
@ManyToOne
@JoinColumn(name = "BD_SETUP_ID", referencedColumnName="ID", nullable = false)
private BDSetup bdSetup;
// bi-directional many-to-one association to BDExtract
@ManyToOne
@JoinColumn(name = "BD_EXTRACT_ID", referencedColumnName="ID", nullable = false)
private BDExtract bdExtract;
@OneToMany(mappedBy = "bdExtractSetup", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<BDExtractSetupColumn> bdExtractSetupColumn = new HashSet<BDExtractSetupColumn>();
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public BDSetup getBdSetup() {
return bdSetup;
}
public void setBdSetup(BDSetup bdSetup) {
this.bdSetup = bdSetup;
}
public void setBdExtract(BDExtract bdExtract) {
this.bdExtract = bdExtract;
}
public BDExtract getBdExtract() {
return bdExtract;
}
public void setExtractAndSetup(BDExtract bdExtract, BDSetup bdSetup) {
this.bdExtract = bdExtract;
this.bdSetup = bdSetup;
}
public Set<BDExtractSetupColumn> getBdExtractSetupColumn() {
return bdExtractSetupColumn;
}
public void setBdExtractSetupColumn(
Set<BDExtractSetupColumn> bdExtractSetupColumn) {
this.bdExtractSetupColumn = bdExtractSetupColumn;
}
}
孙子实体(带有额外列的映射表):
package com.blah.blah.jpa;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity
@Table(name = "BD_EXTRACT_SETUP_COLUMN")
public class BDExtractSetupColumn implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private BDExtractSetupColumnId id = new BDExtractSetupColumnId();
@ManyToOne
@MapsId("bdExtractSetupId")
@JoinColumn(name = "BD_EXTRACT_SETUP_ID", referencedColumnName = "ID", nullable = false)
private BDExtractSetup bdExtractSetup;
@ManyToOne
@MapsId("bdExtractColumnId")
@JoinColumn(name = "BD_EXTRACT_COLUMN_ID", referencedColumnName = "ID", nullable = false)
private BDExtractColumn bdExtractColumn;
@Column(name = "DISPLAY_ORDER")
private Long displayOrder;
/**
* @return the id
*/
public BDExtractSetupColumnId getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(BDExtractSetupColumnId id) {
this.id = id;
}
/**
* @return the bdExtractSetup
*/
public BDExtractSetup getBdExtractSetup() {
return bdExtractSetup;
}
/**
* @param bdExtractSetup the bdExtractSetup to set
*/
public void setBdExtractSetup(BDExtractSetup bdExtractSetup) {
this.bdExtractSetup = bdExtractSetup;
}
/**
* @return the bdExtractColumn
*/
public BDExtractColumn getBdExtractColumn() {
return bdExtractColumn;
}
/**
* @param bdExtractColumn the bdExtractColumn to set
*/
public void setBdExtractColumn(BDExtractColumn bdExtractColumn) {
this.bdExtractColumn = bdExtractColumn;
}
/**
* @return the displayOrder
*/
public Long getDisplayOrder() {
return displayOrder;
}
/**
* @param displayOrder the displayOrder to set
*/
public void setDisplayOrder(Long displayOrder) {
this.displayOrder = displayOrder;
}
}
有一些代码试图删除子代,如下所示,我能够获得bdSetup及其所有内容。
Set<BDExtractSetup> bdExtractSetups = bdSetup.getBdExtractSetups();
bdExtractSetups.clear();
bdSetupDAO.save(bdSetup);
和DAO一样:
package com.blah.blah.jpa.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.blah.blah.jpa.BDSecurity;
import com.blah.blah.jpa.BDSetup;
@Repository
public interface BDSetupDAO extends JpaRepository<BDSetup, Long>{
public BDSetup findByBdSecurityAndName(BDSecurity bdSecurity, String name);
}
我正在尝试使用:
更新bdSetupif(isUpdate) {
Set<BDExtractSetup> bdExtractSetups = bdSetup.getBdExtractSetups();
for (BDExtractSetup bdExtractSetup : bdSetup.getBdExtractSetups()) {
bdExtractSetup.getBdExtractSetupColumn().clear();
}
// bdExtractSetups.clear();
// bdExtractSetupDAO.delete(bdSetup.getBdExtractSetups());
bdSetup.getBdExtractSetups().clear();
// bdSetup = bdSetupDAO.getOne(bdSetup.getId());
// bdExtractSetupDAO.deleteInBatch(bdExtractSetups);
// bdSetup = bdSetupDAO.findOne(bdSetup.getId());
for (int i = 0; i < bdExtracts.size(); i++) {
BDExtract bdExtract = bdExtracts.get(i);
BDExtractSetup bdExtractSetup = new BDExtractSetup();
bdExtractSetup.setBdSetup(bdSetup);
bdExtractSetup.setBdExtract(bdExtract);
Set<BDExtractSetupColumn> tempExtractSetupColumns = new HashSet<BDExtractSetupColumn>();
for (BDExtractDTO bdExtractDTO : mappedBdExtracts) {
if(bdExtract.getId().equals(bdExtractDTO.getId())) {
BDExtractColumn extractColumn = null;
BDExtractSetupColumn extractSetupColumn = null;
for (BDExtractColumnDTO bdExtractColumnDTO : bdExtractDTO.getBdExtractColumns()) {
extractColumn = new BDExtractColumn();
extractColumn.setName(bdExtractColumnDTO.getName());
extractColumn.setBdExtract(bdExtract);
extractSetupColumn = new BDExtractSetupColumn();
extractSetupColumn.setBdExtractColumn(extractColumn);
extractSetupColumn.setBdExtractSetup(bdExtractSetup);
extractSetupColumn.setDisplayOrder(bdExtractColumnDTO.getDisplayOrder());
tempExtractSetupColumns.add(extractSetupColumn);
}
break; //if bdExtractId matches the id in mappedBdExtracts, do not iterate further for bdExtractColumns of extractDTO
}
}
bdExtractSetup.getBdExtractSetupColumn().addAll(tempExtractSetupColumns);
finalBDExtractSetups.add(bdExtractSetup);
}
bdSetup.getBdExtractSetups().addAll(finalBDExtractSetups);
}
return finalBDExtractSetups;
以前的异常消失了,现在得到其他异常:
Hibernate:
insert
into
BD_EXTRACT_SETUP
(BD_EXTRACT_ID, BD_SETUP_ID, id)
values
(?, ?, ?)
31 May 2015 10:08:24,256 [main] WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1, SQLState: 23000
31 May 2015 10:08:24,256 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ORA-00001: unique constraint (BI_DATA.BD_EXTRACT_SETUP_UN1) violated
31 May 2015 10:08:24,262 [main] INFO org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements
这意味着,没有发生删除,直接插入查询被触发。 有什么解决方案吗?
感谢。