I'm attempting to save records to a database table that includes a foreign key to another table using Spring-Boot and Spring Data JPA.
My JSON looks like this:
{
"requestId": 10080,
"auditType": "C",
"auditDate": "2019-06-12T17:25:43.511",
"auditUsername": "cdunstal",
"message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget porttitor velit. Fusce libero augue, tincidunt in vestibulum nec, lobortis tristique eros. Cras tempor est magna, eu dapibus metus bibendum non.",
"isReportable": "Y"
}
My Entity looks like this:
@Entity
@Table(name = "CHANGE_AUDIT")
@SequenceGenerator(name = "CHANGE_AUDIT_PK_SEQ", sequenceName = "CHANGE_AUDIT_PK_SEQ", allocationSize = 1)
public class ChangeAudit {
@Column(name = "AUDIT_ID")
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CHANGE_AUDIT_PK_SEQ")
private Integer id;
@Version
private Long version;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REQUEST_ID")
@NotNull
private ChangeRequest changeRequest;
@Column(name = "AUDIT_TYPE", nullable = false, length = 1)
@NotNull
@Size(max = 1)
private String auditType;
@Column(name = "AUDIT_DATE", nullable = false)
@NotNull
private Date auditDate;
@Column(name = "AUDIT_USER", nullable = false, length = 10)
@NotNull
@Size(max = 10)
private String auditUsername;
@Column(name = "AUDIT_MESSAGE", nullable = false, length = 4000)
@NotNull
@Size(max = 4000)
private String message;
@Column(name = "IS_REPORTABLE", nullable = false, length = 1)
@NotNull
@Size(max = 1)
private String isReportable;
// Constructor, getters and setters omitted.
}
My Controller method is:
@RequestMapping(value = "/changeAudit/create", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody()
public ChangeAudit createChangeAudit(@RequestBody ChangeAudit changeAudit) {
logger.info("Creating new ChangeAudit: " + changeAudit.toString());
return this.changeAuditService.createChangeAudit(changeAudit);
}
I receive the following error:
{
"timestamp": 1560412164364,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.transaction.TransactionSystemException",
"message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction",
"path": "/grade-admin-api/changeAudit/create"
}
Which is caused by:
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:87)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 78 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [au.edu.csu.gradeadmin.api.entity.ChangeAudit] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=changeRequest, rootBeanClass=class au.edu.csu.gradeadmin.api.entity.ChangeAudit, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
So, when saving the ChangeAudit
, it's not taking the requestId
from the JSON and translating that to the ChangeRequest
object in the Entity.
I can't seem to find any documentation or tutorial or any other stack overflow question that solves my problem. I have tried using a different class as the @RequestBody
but it just comes back with null values. I've been stuck on this for two days and need to get passed it, so would appreciate any assistance anyone might be able to offer.
Forgive the brevity, I had to rush the posting. Please let me know if you need more info.
Thanks.
Update - Answer
@user06062019 put me on the right track. I corrected the submitted JSON and added the CascadeType.ALL to the Entity, however, this gave me a different error - that I couldn't insert null into ChangeRequest.pidm.
This is because I had requestId as the foreign key in the submitted JSON, however, it needed to be just id, which is what the parameter in the ChangeRequest class is called. I could then retrieve the ChangeRequest class in the ChangeAuditService, add it to the ChangeAudit object and save it. Voila!
Correct JSON:
{
"changeRequest": {
"id": 10080
},
"auditType": "C",
"auditDate": "2019-06-12T17:36:43.511",
"auditUsername": "someuser",
"message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eget porttitor velit. Fusce libero augue, tincidunt in vestibulum nec, lobortis tristique eros. Cras tempor est magna, eu dapibus metus bibendum non.",
"isReportable": "Y"
}