I have the ff. pojos: i make it short for simplicity
public class CaseOutlineHeader{
@Id
@GeneratedValue(generator = "COH_SequenceStyleGenerator")
@Column(name = "outline_id")
private Long id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "outline_id", nullable = true, referencedColumnName = "outline_id",
foreignKey = @ForeignKey(name = "FK_COH_REF_COD_01"))
private List<CaseOutlineDetails> caseOutlineDetails;
}
public class CaseOutlineDetails{
@Id
@GeneratedValue(generator = "COD_SequenceStyleGenerator")
@Column(name = "ID")
private Long id;
@ManyToOne(targetEntity = MaintCaseEvent.class)
@JoinColumn(name = "EVENT_ID", nullable = false,
foreignKey = @ForeignKey(name = "FK_COD_REF_CASE_EVENT"),
referencedColumnName = "CASE_EVENT_ID")
private MaintCaseEvent eventId;
@Column(name = "outline_id")
private Long outlineId;
}
And then my service: It's pretty straightforward if the passed json of COD contains id that is not null it will update COH along with the COD . else if i passed a null id of COD i will save as a new entry in COD.
@Override
@Transactional
public CaseOutlineHeader update(CaseOutlineHeader caseoutline) {
LOG.info("SERVICE: Updating CaseOutlineHeader...{}", caseoutline);
if (!CollectionUtils.isEmpty(caseoutline.getCaseOutlineDetails())) {
caseoutline.getCaseOutlineDetails().forEach(cod -> {
if (cod.getId() != null) {
cod.setUpdatedBy(cod.getUpdatedBy());
cod.setUpdatedDate(new Date());
caseOutlineHeaderRepository.update(caseoutline);
} else {
cod.setOutlineId(caseoutline.getId());
cod.setCreatedBy("dwade");
caseOutlineDetailsRepository.save(cod);
}
});
}
return caseoutline;
}
Passed json data in swagger:
{
"id": 1,
"caseOutlineDetails": [
{
"eventId": { "id": 1 },
"updatedBy": "kobe",
"id" : 1,
"outlineId" : 1
},
{
"eventId": { "id": 2},
"outlineId" : 1
}
],
"caseType": "string",
"code": "updateC",
"description": "updateD",
"updatedBy": "kobe",
"updatedDate": "2018-07-23T00:55:16.767Z"
}
As you can see i passed a second data in COD which dont have an id property it will be saved. while the first one will be updated which contains an id.
Here is my repo:
@Override
public CaseOutlineHeader update(CaseOutlineHeader caseOutlineHeader) {
em.merge(caseOutlineHeader);
em.flush();
return caseOutlineHeader;
}
@Override
public CaseOutlineDetails save(CaseOutlineDetails caseOutlineDetails) {
LOG.info("REPOSITORY : SAVE = " + caseOutlineDetails);
em.persist(caseOutlineDetails);
return caseOutlineDetails;
}
But in my logger i dont know why it inserts a new record first with id and foreign key only as the value. But on the last line of insert statement is successful
Hibernate: insert into case_outline_details (access_level...
Hibernate: update case_outline_header set access_level=?...
Hibernate: update case_outline_details set access_level=?...
Hibernate: select seq_cod.nextval from dual
Hibernate: insert into case_outline_details (access_level...
It should just be update,update,then insert.
You declared caseOutlineDetails
with cascade = CascadeType.ALL
. So when you're updating a CaseOutlineHeader
, hibernate will automatically update the list, inserting rows if needed. Then you're doing your stuff and insert it again.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.