Reputation: 31
I have a parent record that already exists in my database. I am trying to add a child and associate it to this parent. They share the same class. When I attempt to add the child, it remakes the parent entity. It seems like Hibernate is mistakenly thinking that I am making a new parent. Is it a Hibernate tag or maybe there is something getting passed by value instead of reference?
Entity Definition
@Id
@GeneratedValue(generator="entitySequence", strategy=GenerationType.AUTO)
@SequenceGenerator(name="entitySequence", initialValue=1,
sequenceName="entity_sequence", schema="user_portal")
private Long id;
...
@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST,
CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name="parent_id", referencedColumnName="id")
@JsonBackReference
private Entity parentEntity;
@OneToMany(mappedBy="parentEntity", fetch=FetchType.LAZY,
targetEntity=Entity.class,
cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
@JsonManagedReference
private List<Entity> childEntities;
Controller Code
@RequestMapping(
value = "/add",
method = RequestMethod.POST,
headers = HTTP_ACCEPT_JSON_HEADER,
produces = HTTP_RESPONSE_JSON_HEADER)
public @ResponseBody WebResponse addEntity(@RequestBody Entity s) {
WebResponse wr = new WebDataResponse();
try {
s = EntityService.saveEntity(s);
if (s != null) {
handleSuccess(wr, s, 1);
} else {
handleSuccess(wr, null, "Error adding Entity.", 0);
}
} catch (Exception ex) {
handleException(wr, ex);
}
return wr;
}
Service Code
@Override
@Transactional
public Entity saveEntity(Entity s) {
String entityNumber = s.getEntityNumber();
boolean isAddendum = StringUtils.countOccurrencesOf(entityNumber, "-") == 4;
if(isAddendum) {
Entity parent = getEntityByNumber(entityNumber.substring(0,entityNumber.lastIndexOf("-")));
if(parent !=null) {
s.setParentEntity(parent);
}else {
return null;
}
}
s.setCreatedBy("admin");
s.setCreatedDate(new Date());
s = entityRepository.save(s);
return s;
}
@Override
@Transactional(readOnly = true)
public Entity getEntityByNumber(String entityNum) {
Entity s = entityRepository
.findByEntityNumber(entityNum);
return s;
}
Any help is greatly appreciated! Thank you!
Upvotes: 2
Views: 1629
Reputation: 31
Removing CascadeType.PERSIST from my parentEntity fixed this issue.
I would also recommend NOT manually inserting test variables. It was much better making API test calls using an application like Postman. This gave me a much better idea about how to fix the problem (I received an error rather than this duplication issue).
Upvotes: 1
Reputation: 1341
You are using a bidirectional association so besides set parent to child you have to add child to parent i.e. parent.getChildEntities().add(s)
. To be more clear:
@Override
@Transactional
public Entity saveEntity(Entity s) {
String entityNumber = s.getEntityNumber();
boolean isAddendum = StringUtils.countOccurrencesOf(entityNumber, "-") == 4;
if(isAddendum) {
Entity parent = getEntityByNumber(entityNumber.substring(0,entityNumber.lastIndexOf("-")));
if (parent !=null) {
s.setParentEntity(parent);
parent.getChildEntities().add(s);
} else {
return null;
}
}
s.setCreatedBy("admin");
s.setCreatedDate(new Date());
s = entityRepository.save(s);
return s;
}
Upvotes: 0