I have two tables one is parent and other one is child. When I am trying to save initially, I am able to insert values in both the tables if values not present in Parent table. But at the time of update/insert the values in child table, it is inserting duplicate values.
@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"
}
}
If I am passing this request and values are not present in both the tables then it should insert the values in both the tables which is working as expected with above code. But at the time of update it is going inside the loop and inserting duplicate values. I am trying to update DESCRIPTION in child table if BINDING is present if not it should insert BINDING plus DESCRIPTION
I fixed this by separating Save and Update methods. Thanks to all.