spring-data-jpa Sping Boot -批量插入强制执行Update语句

oknwwptz  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(182)

我正在尝试在MySQL表中批量插入记录。
当我在没有组合键的情况下进行批量插入时,它的工作原理就像一个魅力。
但是,当我分配组合键时。
在我的表方案中:Id是自动递增的主键,ENODEB和HOUR_DATE_TIME是我的普通列,它们没有标记为组合键,但我在实体类中将它们组合在一起。
当我这样做的时候。
它执行select语句,然后执行Insert语句,最后执行update语句。
由于记录尚未插入到数据库中,因此出现以下错误:
导致的异常:批更新从更新[0]返回意外的行计数;实际行数:0;应为:1;执行的语句:更新标识符,设置下 Package 丢失时间=?、下 Package 丢失时间密度=?、下 Package 丢失时间数量=?、下机架左减速器密度=?、下机架左减速器数量=?、下机架左减速器减速率=?、下机架右减速器减速率=?、下机架右减速器密度=?、下机架左减速器减速率=?、下机架右减速器减速率=?、下机架右减速器减速率=?、下机架右减速器减速率=?、下机架右减速器减速率=?、下机架右减速器减速率=?、下机架左减速器减速器密度=?、下机架右减速器减速器减速率=?、V_RAN_ACC=?,V_RAN_ACC_DEN=?,V_RAN_ACC_NUM=?,加速S1成功率=?,加速S1成功率DEN =?,加速S1成功率NUM =?,UL_PKT_LOSS_RT=?,UL_PKT_LOSS_RT_DEN=?,UL_PKT_LOSS_RT_NUM=?,小区类别=?,客户端指南=?,小时日期=?,站点指南=?,地点项目指南=?,其中ENODEB=?且小时日期时间=?
正如我在互联网上检查的那样,SaveAll方法总是根据实体类中定义的键来检查唯一性。由于是第一次插入,所以不应该执行更新。有人能帮忙吗?

实体类

package com.vizalogix.insite.dx.entities.SVDXDB;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Proxy;

import javax.persistence.*;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

@Getter
@Setter
@Entity
@Table(name = "idas_kpis")
@JsonIgnoreProperties(ignoreUnknown = true, value={"hibernateLazyInitializer", "handler"})
@IdClass(IdasKpisId.class)
@Proxy(lazy = false)
public class IdasKpis {

//    //@GeneratedValue(strategy = GenerationType.AUTO)
//    @GeneratedValue(generator = "idas")
//    @GenericGenerator(name = "idas", strategy = "increment")
//    @Column(name = "ID")
//    private Integer id;
    @Id
    @Column(name = "ENODEB", updatable = false, nullable = false)
    String cell;

    @Id
    @Column(name = "HOUR_DATE_TIME", updatable = false, nullable = false)
    java.util.Date datetime;

   // private IdasKpisId kpisId;

    @JsonIgnore
    @Column(name = "HOUR_DATE")
    private Date date;

    /*@Id
    @JsonIgnore
    @Column(name = "HOUR_DATE_TIME")
    private Date datetime;

    @Id
    @JsonIgnore
    @Column(name = "ENODEB")
    private String cell;*/

    @JsonIgnore
    @Column(name = "Acc_S1_Succ_Rate")
    private String D_S1_FR_L_ER_ECEL;

    @JsonIgnore
    @Column(name = "Acc_S1_Succ_Rate_NUM")
    private String D_S1_FR_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "Acc_S1_Succ_Rate_DEN")
    private String D_S1_FR_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "UL_PKT_LOSS_RT")
    private String D_UL_TP_L_ER_ECEL;

    @JsonIgnore
    @Column(name = "UL_PKT_LOSS_RT_NUM")
    private String D_UL_TP_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "UL_PKT_LOSS_RT_DEN")
    private String D_UL_TP_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "DL_PKT_LOSS_RT")
    private String D_DL_TP_L_ER_ECEL;

    @JsonIgnore
    @Column(name = "DL_PKT_LOSS_RT_NUM")
    private String D_DL_TP_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "DL_PKT_LOSS_RT_DEN")
    private String D_DL_TP_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "V_RAN_ACC")
    private String D_RAN_ACC_L_ER_ECEL;

    @JsonIgnore
    @Column(name = "V_RAN_ACC_DEN")
    private String D_RAN_ACC_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "V_RAN_ACC_NUM")
    private String D_RAN_ACC_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "V_ERB1_RET")
    private String D_OVR_RET_L_ER_ECEL;

    @JsonIgnore
    @Column(name = "V_ERB1_RET_DEN")
    private String D_OVR_RET_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "V_ERB1_RET_NUM")
    private String D_OVR_RET_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "D_IRAFHO_SR_L_ER_ECEL_RATE")
    private String D_IRAFHO_SR_L_ER_ECEL_RATE;

    @JsonIgnore
    @Column(name = "D_IRAFHO_SR_L_ER_ECEL_DEN")
    private String D_IRAFHO_SR_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "D_IRAFHO_SR_L_ER_ECEL_NUM")
    private String D_IRAFHO_SR_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "D_RACC_FR_L_ER_ECEL_RATE")
    private String D_RACC_FR_L_ER_ECEL_RATE;

    @JsonIgnore
    @Column(name = "D_RACC_FR_L_ER_ECEL_DEN")
    private String D_RACC_FR_L_ER_ECEL_DEN;

    @JsonIgnore
    @Column(name = "D_RACC_FR_L_ER_ECEL_NUM")
    private String D_RACC_FR_L_ER_ECEL_NUM;

    @JsonIgnore
    @Column(name = "client_guid")
    private String clientGuid;

    @JsonIgnore
    @Column(name = "site_guid")
    private String siteGuid;

    @JsonIgnore
    @Column(name = "cell_category")
    private String cellCategory;

    @JsonIgnore
    @Column(name = "venue_item_guid")
    private String venueItemGuid;
}

插入声明

for (int i=0; i<csvArray.length(); i++) {
                IdasKpis kpi = new IdasKpis();
                IdasKpisId kpiId = new IdasKpisId();
                SimpleDateFormat sdf_time = new SimpleDateFormat("MM/dd/yyyy");
                SimpleDateFormat sdf_hour = new SimpleDateFormat("HH");
                java.util.Date hour = sdf_hour.parse(csvArray.getJSONObject(i).getString("HOUR").substring(10, 12));
                java.util.Date hour_time = sdf_time.parse(csvArray.getJSONObject(i).getString("HOUR"));
                java.sql.Date date_time = new Date(hour_time.getTime());
                java.sql.Date hours = new Date(hour.getTime());

                kpi.setDatetime(date_time);
                kpi.setCell(csvArray.getJSONObject(i).getString("CELL"));

                kpi.setDate(hours);
                //kpi.setKpisId(kpiId);
                kpi.setD_S1_FR_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL (%)")) ? csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL (%)") : "0");
                kpi.setD_S1_FR_L_ER_ECEL_NUM(isNotEmpty(csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL_NUM (#)") : "0");
                kpi.setD_S1_FR_L_ER_ECEL_DEN(isNotEmpty(csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_S1_FR_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_UL_TP_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL (#)")) ? csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL (#)") : "0");
                kpi.setD_UL_TP_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL_NUM (#)") : "0");
                kpi.setD_UL_TP_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_UL_TP_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_RAN_ACC_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL (%)")) ? csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL (%)"): "0");
                kpi.setD_RAN_ACC_L_ER_ECEL_DEN(isNotEmpty(csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_RAN_ACC_L_ER_ECEL_NUM(isNotEmpty(csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_RAN_ACC_L_ER_ECEL_NUM (#)") : "0");
                kpi.setD_OVR_RET_L_ER_ECEL(isNotEmpty(csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL (%)")) ? csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL (%)") : "0");
                kpi.setD_OVR_RET_L_ER_ECEL_DEN(isNotEmpty(csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_OVR_RET_L_ER_ECEL_NUM(isNotEmpty(csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_OVR_RET_L_ER_ECEL_NUM (#)") : "0");
                kpi.setD_IRAFHO_SR_L_ER_ECEL_RATE(isNotEmpty(csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL (%)")) ? csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL (%)") : "0");
                kpi.setD_IRAFHO_SR_L_ER_ECEL_DEN(isNotEmpty(csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_IRAFHO_SR_L_ER_ECEL_NUM(isNotEmpty(csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_IRAFHO_SR_L_ER_ECEL_NUM (#)") : "0");
                kpi.setD_RACC_FR_L_ER_ECEL_RATE(isNotEmpty(csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL (%)")) ? csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL (%)") : "0");
                kpi.setD_RACC_FR_L_ER_ECEL_DEN(isNotEmpty(csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL_DEN (#)")) ? csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL_DEN (#)") : "0");
                kpi.setD_RACC_FR_L_ER_ECEL_NUM(isNotEmpty(csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL_NUM (#)")) ? csvArray.getJSONObject(i).getString("D_RACC_FR_L_ER_ECEL_NUM (#)") : "0");
                kpi.setClientGuid(clientGuid);
                kpi.setCellCategory("1");
                kpi.setSiteGuid(siteGuid);
                kpi.setVenueItemGuid(venueItem);

                kpiList.add(kpi);
            }
            kpiDao.saveAll(kpiList);

组合键类

package com.vizalogix.insite.dx.entities.SVDXDB;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.Date;

@Getter
@Setter
public class IdasKpisId implements Serializable {

    @Column(name = "ENODEB", updatable = false, nullable = false)
    String cell;

    @Column(name = "HOUR_DATE_TIME", updatable = false, nullable = false)
    Date datetime;
}
7qhs6swi

7qhs6swi1#

如果你看到saveAll()源代码,它会在内部调用save(),然后首先通过空值检查来检查正在进行的实体是否是新的:

public <S extends T> S save(S entity) {

        Assert.notNull(entity, "Entity must not be null.");

        if (entityInformation.isNew(entity)) { //here if you check `isNew` code, it checks for nullability of your `Id` attribute.
            em.persist(entity);
            return entity;
        } else {
            return em.merge(entity); //upsert 
        }
    }

现在,我可以在您的代码中看到,您提到您的Id字段是不可空的&这就是原因,save调用将进行upsert(这里是em.merge),即使它的第一个记录。
对于您的情况,请尝试从Id字段中删除nullable = false,看看是否能正常工作。

相关问题