首页 > 解决方案 > 为什么 JPA 会删除多对一关系的第一个元素?

问题描述

更新 mariadb 上的记录后,jpa 删除了单对多对多关系的第一个元素。

我有这个实体(Getters 和 Setter 被省略)

@Entity
@Table(name= "regulation")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Regulation {
  @Id
  @Column(name = "ID_REGULATION")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  @NotNull
  @Column(name = "token")
  private String token;
  @NotNull
  @Column(name = "name")
  private String name;
  @NotNull
  @Column(name = "id_transmitter")
  private Long transmitter;
  @NotNull
  @Column(name = "id_document")
  private Long document;
  @Column(name = "is_valid", nullable = false)
  private boolean isValid = true;


  @Override
  public String toString() {
    return "Regulation [id=" + id + ", token=" + token + ", name=" + name + ", transmitter="
        + transmitter + ", document=" + document + ", isValid=" + isValid + ", entity=" + entity
        + ", sectorIndustry=" + sectorIndustry + ", department=" + department + "]";
  }

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "regulationEntity", cascade= CascadeType.ALL, orphanRemoval = true)
  private List<RegulationEntity> entity;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "regulationDepartment", cascade= CascadeType.ALL, orphanRemoval = true)
  private List<RegulationDepartment> department;
}

@Entity
@Table( name= "regulation_entity")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class RegulationEntity {

  @Id
  @Column(name = "ID_REGULATION_ENTITY")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  @Override
  public String toString() {
    return "RegulationEntity [id=" + id + ", entity=" + entity + "]";
  }
  @NotNull
  @Column(name = "id_entity")
  private Long entity;
  @ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
  @JoinColumn(name = "FK_ID_REGULATION", referencedColumnName="ID_REGULATION")
  private Regulation regulationEntity;
}

@Entity
@Table( name= "regulation_department")
public class RegulationDepartment {

  @Override
  public String toString() {
    return "RegulationDepartment [id=" + id + ", department=" + department + "]";
  }
  @Id
  @Column(name = "ID_REGULATION_DEPARTMENT")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  @NotNull
  @Column(name = "id_department")
  private Long department;
  @ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
  @JoinColumn(name = "FK_ID_REGULATION", referencedColumnName="ID_REGULATION")
  private Regulation regulationDepartment;
} 

而这堂课

public class RegulationVO {

  private Long id;
  private String token;
  private String name;
  private Long transmitter;
  private Long document;
  private boolean isValid;
  private List<Long> entity;
  private List<Long> department;
}

并使用 CrudRepository

public interface RegulationRepository extends CrudRepository<Regulation, Long>{ 
}

一个更新过程

@Transactional
  public ResponseEntity<ResponseBean> updateRegulation(RegulationVO regulationVO){
    ResponseBean response = new ResponseBean();
    try {
      Regulation regulation = this.getRegulationUpdated(regulationVO);
      Regulation saved = this.regulationRepository.save(regulation);
      log.info(saved.toString());
      response.setHttpStatus(HttpStatus.OK);
    }catch(Exception e) {
      log.error(e.getMessage(), e);
      response.setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR);
    }
    return new ResponseEntity<>(response, response.getHttpStatus());
  }

  public Regulation getRegulationUpdated(RegulationVO regulationVO) {
    Regulation regulation = this.regulationRepository.findById(regulationVO.getId()).get();
    regulation.setToken(regulationVO.getToken());
    regulation.setName(regulationVO.getName());
    regulation.setTransmitter(regulationVO.getTransmitter());
    regulation.setDocument(regulationVO.getDocument());

    List<RegulationEntity> listaEntities = new ArrayList<>();
    for(Long idEntity : regulationVO.getEntity()) {
      log.info(idEntity.toString());
      RegulationEntity regulationEntity = new RegulationEntity();
      regulationEntity.setEntity(idEntity);
      regulationEntity.setRegulationEntity(regulation);
      listaEntities.add(regulationEntity);
    }
    regulation.getEntity().clear();
    regulation.getEntity().addAll(listaEntities);

    List<RegulationDepartment> listaDepartments = new ArrayList<>();
    for(Long idDepartment : regulationVO.getDepartment()) {
      log.info(idDepartment.toString());
      RegulationDepartment regulationDepartment = new RegulationDepartment();
      regulationDepartment.setDepartment(idDepartment);
      regulationDepartment.setRegulationDepartment(regulation);
      listaDepartments.add(regulationDepartment);

    }
    regulation.getDepartment().clear();
    regulation.getDepartment().addAll(listaDepartments);

    return regulation;
  }

但是在保存更新的对象后,JPA 删除了我的RegulationDepartment List 的第一条记录。

保存后输出

Regulation [id=29, token=002AV01, name=Regulation, transmitter=1, document=1, isValid=true, entity=[RegulationEntity [id=179, entity=5], RegulationEntity [id=180, entity=8], RegulationEntity [id=181, entity=9]],  department=[RegulationDepartment [id=165, department=1], RegulationDepartment [id=166, department=2], RegulationDepartment [id=167, department=3]]]

记录 JPA

2019-07-19 08:49:01.688 DEBUG 5724 --- [nio-8093-exec-1] org.hibernate.SQL                        : delete from regulation_entity where id_regulation_entity=?
2019-07-19 08:49:01.688 TRACE 5724 --- [nio-8093-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [177]
2019-07-19 08:49:01.688 DEBUG 5724 --- [nio-8093-exec-1] org.hibernate.SQL                        : delete from regulation_department where id_regulation_department=?
2019-07-19 08:49:01.688 TRACE 5724 --- [nio-8093-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [165]
2019-07-19 08:49:01.703 DEBUG 5724 --- [nio-8093-exec-1] org.hibernate.SQL                        : delete from regulation_entity where id_regulation_entity=?
2019-07-19 08:49:01.703 TRACE 5724 --- [nio-8093-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [178]

任何想法为什么会发生这种情况?

对于没有发生并且是相同类型的关系的列表RegulationEntity。

标签: jpamariadb

解决方案


推荐阅读