JPA Hibernate删除子实体问题的子代(使用spring JPARepository)

时间:2015-05-30 13:06:41

标签: hibernate jpa spring-data-jpa

我正在使用现有数据库表(在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);

}

我正在尝试使用:

更新bdSetup
if(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

这意味着,没有发生删除,直接插入查询被触发。 有什么解决方案吗?

感谢。

1 个答案:

答案 0 :(得分:0)

您似乎正在向某个托管实体实例分配新的集合实例。

您可以找到有关此hereherehere的更多信息。