如何在不使用 Java Spring Boot 插入新值的情况下更新 table 中的现有值
How to update existing value in table without inserting new using Java SpringBoot
我有两个 table,一个是 parent,另一个是 child。当我最初尝试保存时,如果 Parent table 中不存在值,我可以在两个 table 中插入值。但是在 update/insert child table 中的值时,它正在插入重复值。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RuleApi {
Long id;
private String market;
private int modelYear;
private String vehicleLine;
private String vehicleLineName;
private String locale;
private String binding;
private String description;
private String createUser;
private String updateUser;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DescriptorSaveRequest {
@Valid
@NotNull
RuleApi rule;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "MNAVS03_DESCRIPTOR_CONTEXT")
@EntityListeners(AuditingEntityListener.class)
public class DescriptorContext implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Setter(value = AccessLevel.NONE)
@Column(name = "NAVS03_DESCRIPTOR_CONTEXT_K")
private Long id;
@Column(name = "NAVS03_MARKET_N")
private String market;
@Column(name = "NAVS03_MODEL_YEAR_R")
private Integer modelYear;
@Column(name = "NAVS03_VEHICLE_LINE_C")
private String vehicleLine;
@Column(name = "NAVS03_VEHICLE_LINE_N")
private String vehicleLineName;
@Column(name = "NAVS03_LOCALE_N")
private String locale;
@Column(name = "NAVS03_CREATE_USER_C", nullable = false)
private String createUserId;
@CreationTimestamp
@Column(name = "NAVS03_CREATE_S")
private Timestamp createTimestamp;
@Column(name = "NAVS03_LAST_UPDT_USER_C", nullable = false)
private String updateUserId;
@UpdateTimestamp
@Column(name = "NAVS03_LAST_UPDT_S")
private Timestamp updateTimestamp;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "MNAVS04_DESCRIPTOR_RULE")
@EntityListeners(AuditingEntityListener.class)
public class DescriptorRule implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Setter(value = AccessLevel.NONE)
@Column(name = "NAVS04_DESCRIPTOR_RULE_K")
private Long id;
@JoinColumn(name = "NAVS03_DESCRIPTOR_CONTEXT_K", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
private DescriptorContext descriptorContextId;
@Column(name = "NAVS04_BINDING_N",
unique = true)
private String binding;
@Column(name = "NAVS04_DESCRIPTOR_RULE_X")
private String description;
@Column(name = "NAVS04_CREATE_USER_C", nullable = false)
private String createUserId;
@CreationTimestamp
@Column(name = "NAVS04_CREATE_S")
private Timestamp createTimestamp;
@Column(name = "NAVS04_LAST_UPDT_USER_C", nullable = false)
private String updateUserId;
@UpdateTimestamp
@Column(name = "NAVS04_LAST_UPDT_S")
private Timestamp updateTimestamp;
}
@ApiOperation(value = "Create/Update Feature Descriptions", notes = "Create/Update a descriptions based on the given input")
@PostMapping("/descriptor/saveFeatures")
public ResponseEntity<BaseBodyResponse<String>> saveFeatureDescriptions(@Valid @RequestBody DescriptorSaveRequest descriptorSaveRequest) throws Exception {
this.descriptorContextService.saveFeatureDescriptions(
this.descriptorContextMapper.mapDescriptorContext(descriptorSaveRequest),
this.descriptorContextMapper.mapDescriptorRule(descriptorSaveRequest)
);
return ResponseEntity.ok(BaseBodyResponse.result("Saved Successfully"));
}
@Service
public class DescriptorContextService {
//SaveFeatureDescriptions
public void saveFeatureDescriptions(DescriptorContext descriptorContext, DescriptorRule descriptorRule) throws Exception {
DescriptorContext descriptorContext1 =
this.descriptorContextRepository.findByMarketAndModelYearAndVehicleLineAndVehicleLineNameAndLocale(
descriptorContext.getMarket(),
descriptorContext.getModelYear(),
descriptorContext.getVehicleLine(),
descriptorContext.getVehicleLineName(),
descriptorContext.getLocale());
if (descriptorContext1 == null) {
// add a new context
descriptorContext1 = descriptorContextRepository.save(DescriptorContext.builder()
.market(descriptorContext.getMarket())
.modelYear(descriptorContext.getModelYear())
.vehicleLine(descriptorContext.getVehicleLine())
.vehicleLineName(descriptorContext.getVehicleLineName())
.locale(descriptorContext.getLocale())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
}
Long contextId = descriptorContext1.getId();
List<DescriptorRule> rule = this.descriptorRuleRepository.findByDescriptorContextId(contextId);
if (rule.size() == 0) {
// add a new rule
this.descriptorRuleRepository.save(DescriptorRule.builder()
.descriptorContextId(descriptorContext1)
.binding(descriptorRule.getBinding())
.description(descriptorRule.getDescription())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
} else {
// update a existing rule
for (DescriptorRule descriptorRule1 : rule) {
if (descriptorRule1.getBinding().equals(descriptorRule.getBinding())) {
descriptorRule1.setDescription(descriptorRule.getDescription());
descriptorRule1.setupdateUserId(descriptorRule.getupdateUserId());
this.descriptorRuleRepository.save(descriptorRule1);
} else {
this.descriptorRuleRepository.save(DescriptorRule.builder()
.descriptorContextId(descriptorContext1)
.binding(descriptorRule.getBinding())
.description(descriptorRule.getDescription())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
}
}
}
}
}
}
@Component
public class DescriptorContextMapper {
public DescriptorContext mapDescriptorContext(DescriptorSaveRequest descriptorSaveRequest) {
return DescriptorContext.builder()
.market(descriptorSaveRequest.getRule().getMarket())
.vehicleLine(descriptorSaveRequest.getRule().getVehicleLine())
.vehicleLineName(descriptorSaveRequest.getRule().getVehicleLineName())
.modelYear(descriptorSaveRequest.getRule().getModelYear())
.locale(descriptorSaveRequest.getRule().getLocale())
.createUserId(descriptorSaveRequest.getRule().getCreateUser())
.updateUserId(descriptorSaveRequest.getRule().getUpdateUser())
.build();
}
public DescriptorRule mapDescriptorRule(DescriptorSaveRequest descriptorSaveRequest) {
return DescriptorRule.builder()
.id(descriptorSaveRequest.getRule().getId())
.binding(descriptorSaveRequest.getRule().getBinding())
.description(descriptorSaveRequest.getRule().getDescription())
.createUserId(descriptorSaveRequest.getRule().getCreateUser())
.updateUserId(descriptorSaveRequest.getRule().getUpdateUser())
.build();
}
}
{
"rule": {
"binding": "5003",
"description": "Test new 5003-2023 Escape",
"locale": "fr_CA",
"market": "WANAC",
"modelYear": 2023,
"vehicleLine": "TMC",
"vehicleLineName": "Escape",
"createUser": "rdongre",
"updateUser": "rdongre"
}
}
如果我正在传递此请求并且值不存在于两个 table 中,那么它应该将值插入两个 table 中,这与上面的代码按预期工作。但是在更新时它进入循环并插入重复值。我正在尝试更新 child table 中的 DESCRIPTION 如果存在 BINDING 如果不存在则应该插入 BINDING 加上 DESCRIPTION
我通过分离保存和更新方法解决了这个问题。感谢大家。
我有两个 table,一个是 parent,另一个是 child。当我最初尝试保存时,如果 Parent table 中不存在值,我可以在两个 table 中插入值。但是在 update/insert child table 中的值时,它正在插入重复值。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RuleApi {
Long id;
private String market;
private int modelYear;
private String vehicleLine;
private String vehicleLineName;
private String locale;
private String binding;
private String description;
private String createUser;
private String updateUser;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DescriptorSaveRequest {
@Valid
@NotNull
RuleApi rule;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "MNAVS03_DESCRIPTOR_CONTEXT")
@EntityListeners(AuditingEntityListener.class)
public class DescriptorContext implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Setter(value = AccessLevel.NONE)
@Column(name = "NAVS03_DESCRIPTOR_CONTEXT_K")
private Long id;
@Column(name = "NAVS03_MARKET_N")
private String market;
@Column(name = "NAVS03_MODEL_YEAR_R")
private Integer modelYear;
@Column(name = "NAVS03_VEHICLE_LINE_C")
private String vehicleLine;
@Column(name = "NAVS03_VEHICLE_LINE_N")
private String vehicleLineName;
@Column(name = "NAVS03_LOCALE_N")
private String locale;
@Column(name = "NAVS03_CREATE_USER_C", nullable = false)
private String createUserId;
@CreationTimestamp
@Column(name = "NAVS03_CREATE_S")
private Timestamp createTimestamp;
@Column(name = "NAVS03_LAST_UPDT_USER_C", nullable = false)
private String updateUserId;
@UpdateTimestamp
@Column(name = "NAVS03_LAST_UPDT_S")
private Timestamp updateTimestamp;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "MNAVS04_DESCRIPTOR_RULE")
@EntityListeners(AuditingEntityListener.class)
public class DescriptorRule implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Setter(value = AccessLevel.NONE)
@Column(name = "NAVS04_DESCRIPTOR_RULE_K")
private Long id;
@JoinColumn(name = "NAVS03_DESCRIPTOR_CONTEXT_K", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
private DescriptorContext descriptorContextId;
@Column(name = "NAVS04_BINDING_N",
unique = true)
private String binding;
@Column(name = "NAVS04_DESCRIPTOR_RULE_X")
private String description;
@Column(name = "NAVS04_CREATE_USER_C", nullable = false)
private String createUserId;
@CreationTimestamp
@Column(name = "NAVS04_CREATE_S")
private Timestamp createTimestamp;
@Column(name = "NAVS04_LAST_UPDT_USER_C", nullable = false)
private String updateUserId;
@UpdateTimestamp
@Column(name = "NAVS04_LAST_UPDT_S")
private Timestamp updateTimestamp;
}
@ApiOperation(value = "Create/Update Feature Descriptions", notes = "Create/Update a descriptions based on the given input")
@PostMapping("/descriptor/saveFeatures")
public ResponseEntity<BaseBodyResponse<String>> saveFeatureDescriptions(@Valid @RequestBody DescriptorSaveRequest descriptorSaveRequest) throws Exception {
this.descriptorContextService.saveFeatureDescriptions(
this.descriptorContextMapper.mapDescriptorContext(descriptorSaveRequest),
this.descriptorContextMapper.mapDescriptorRule(descriptorSaveRequest)
);
return ResponseEntity.ok(BaseBodyResponse.result("Saved Successfully"));
}
@Service
public class DescriptorContextService {
//SaveFeatureDescriptions
public void saveFeatureDescriptions(DescriptorContext descriptorContext, DescriptorRule descriptorRule) throws Exception {
DescriptorContext descriptorContext1 =
this.descriptorContextRepository.findByMarketAndModelYearAndVehicleLineAndVehicleLineNameAndLocale(
descriptorContext.getMarket(),
descriptorContext.getModelYear(),
descriptorContext.getVehicleLine(),
descriptorContext.getVehicleLineName(),
descriptorContext.getLocale());
if (descriptorContext1 == null) {
// add a new context
descriptorContext1 = descriptorContextRepository.save(DescriptorContext.builder()
.market(descriptorContext.getMarket())
.modelYear(descriptorContext.getModelYear())
.vehicleLine(descriptorContext.getVehicleLine())
.vehicleLineName(descriptorContext.getVehicleLineName())
.locale(descriptorContext.getLocale())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
}
Long contextId = descriptorContext1.getId();
List<DescriptorRule> rule = this.descriptorRuleRepository.findByDescriptorContextId(contextId);
if (rule.size() == 0) {
// add a new rule
this.descriptorRuleRepository.save(DescriptorRule.builder()
.descriptorContextId(descriptorContext1)
.binding(descriptorRule.getBinding())
.description(descriptorRule.getDescription())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
} else {
// update a existing rule
for (DescriptorRule descriptorRule1 : rule) {
if (descriptorRule1.getBinding().equals(descriptorRule.getBinding())) {
descriptorRule1.setDescription(descriptorRule.getDescription());
descriptorRule1.setupdateUserId(descriptorRule.getupdateUserId());
this.descriptorRuleRepository.save(descriptorRule1);
} else {
this.descriptorRuleRepository.save(DescriptorRule.builder()
.descriptorContextId(descriptorContext1)
.binding(descriptorRule.getBinding())
.description(descriptorRule.getDescription())
.createUserId(descriptorContext.getCreateUserId())
.updateUserId(descriptorContext.getUpdateUserId())
.build());
}
}
}
}
}
}
@Component
public class DescriptorContextMapper {
public DescriptorContext mapDescriptorContext(DescriptorSaveRequest descriptorSaveRequest) {
return DescriptorContext.builder()
.market(descriptorSaveRequest.getRule().getMarket())
.vehicleLine(descriptorSaveRequest.getRule().getVehicleLine())
.vehicleLineName(descriptorSaveRequest.getRule().getVehicleLineName())
.modelYear(descriptorSaveRequest.getRule().getModelYear())
.locale(descriptorSaveRequest.getRule().getLocale())
.createUserId(descriptorSaveRequest.getRule().getCreateUser())
.updateUserId(descriptorSaveRequest.getRule().getUpdateUser())
.build();
}
public DescriptorRule mapDescriptorRule(DescriptorSaveRequest descriptorSaveRequest) {
return DescriptorRule.builder()
.id(descriptorSaveRequest.getRule().getId())
.binding(descriptorSaveRequest.getRule().getBinding())
.description(descriptorSaveRequest.getRule().getDescription())
.createUserId(descriptorSaveRequest.getRule().getCreateUser())
.updateUserId(descriptorSaveRequest.getRule().getUpdateUser())
.build();
}
}
{
"rule": {
"binding": "5003",
"description": "Test new 5003-2023 Escape",
"locale": "fr_CA",
"market": "WANAC",
"modelYear": 2023,
"vehicleLine": "TMC",
"vehicleLineName": "Escape",
"createUser": "rdongre",
"updateUser": "rdongre"
}
}
如果我正在传递此请求并且值不存在于两个 table 中,那么它应该将值插入两个 table 中,这与上面的代码按预期工作。但是在更新时它进入循环并插入重复值。我正在尝试更新 child table 中的 DESCRIPTION 如果存在 BINDING 如果不存在则应该插入 BINDING 加上 DESCRIPTION
我通过分离保存和更新方法解决了这个问题。感谢大家。