Heya, fun issue I’m trying to work out. I have an entity called TermConcept
, which has a whack of child entities, and a parent entity. I have code which is attempting to delete these, along with all their related entities. If you want the gist of the issue head to the bottom, otherwise, here are my entities to start with:
TermConcept
@Entity
@Table(name = "TRM_CONCEPT"}, indexes = {})
public class TermConcept implements Serializable {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "myParent", cascade = {})
private List<TermConceptParentChildLink> myChildren;
@OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "myChild")
private List<TermConceptParentChildLink> myParents;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CODESYSTEM_PID", referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_CONCEPT_PID_CS_PID"))
private TermCodeSystemVersion myCodeSystem;
@OneToMany(mappedBy = "myConcept", orphanRemoval = false, fetch = FetchType.LAZY)
private Collection<TermConceptProperty> myProperties;
@OneToMany(mappedBy = "myConcept", orphanRemoval = false, fetch = FetchType.LAZY)
private Collection<TermConceptDesignation> myDesignations;
@Column(name = "CODEVAL", nullable = false)
private String myCode;
public List<TermConceptParentChildLink> getChildren() {
if (myChildren == null) {
myChildren = new ArrayList<>();
}
return myChildren;
}
public Collection<TermConceptDesignation> getDesignations() {
if (myDesignations == null) {
myDesignations = new ArrayList<>();
}
return myDesignations;
}
public Collection<TermConceptProperty> getProperties() {
if (myProperties == null) {
myProperties = new ArrayList<>();
}
return myProperties;
}
}
TermConceptParentChildLink
@Entity
@Table(name = "TRM_CONCEPT_PC_LINK", indexes = {})
public class TermConceptParentChildLink implements Serializable {
@Id()
@SequenceGenerator(name = "SEQ_CONCEPT_PID", sequenceName = "SEQ_CONCEPT_PID")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_PID")
@Column(name = "PID")
private Long myId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CHILD_PID", nullable = false, referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_CHILD"))
private TermConcept myChild;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CODESYSTEM_PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_CS"))
private TermCodeSystemVersion myCodeSystem;
@ManyToOne(fetch = FetchType.LAZY, cascade = {})
@JoinColumn(name = "PARENT_PID", nullable = false, referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_PARENT"))
private TermConcept myParent;
}
TermConceptDesignation
@Entity
@Table(name = "TRM_CONCEPT_DESIG", indexes={})
public class TermConceptDesignation implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CONCEPT_PID", referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_CONCEPTDESIG_CONCEPT"))
private TermConcept myConcept;
}
TermConceptProperty
@Entity
@Table(name = "TRM_CONCEPT_PROPERTY", uniqueConstraints = {})
public class TermConceptProperty implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CONCEPT_PID", referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_CONCEPTPROP_CONCEPT"))
private TermConcept myConcept;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CS_VER_PID", nullable = true, referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_CONCEPTPROP_CSV"))
private TermCodeSystemVersion myCodeSystemVersion;
}
And now I have some code in which I delete a subset of these TermConcept, along with any of their children.
@Transactional
public void deleteTermConceptsWithCode(List<String> codes) {
for (String code: codes) {
Optional<TermConcept> opt = myTermConceptDao.findByCode(code);
if (opt.isPresent()) {
TermConcept concept = opt.get()
deleteConceptAndChildren(concept);
}
}
private void deleteConceptAndChildren(TermConcept concept) {
for (TermConceptParentChildLink nextChildLink : theConcept.getChildren()) {
deleteConceptAndChildren(nextChildLink.getChild(), );
}
myConceptParentChildLinkDao.deleteByConceptPid(theConcept.getId());
myConceptDesignationDao.deleteAll(theConcept.getDesignations()
myConceptPropertyDao.deleteAll(theConcept.getProperties());
//myConceptDao.deleteByPid(theConcept.getId()); <-- This actually deletes concepts!
myConceptDao.deleteById(theConcept.getId()); // <-- this does not!
}
The behaviour i’m experiencing is that when i use myConceptDao.deleteById()
, which is a standard method of spring-data-jpa, the deletes just…don’t seem to happen. If however, I use my custom deleteByPid()
operation, those deletes happen no problem. Here is the definition of that dao
@Modifying
@Query("DELETE FROM TermConcept t WHERE t.myId = :pid")
void deleteByPid(@Param("pid") Long theId);
Am I missing something fundamental here? Should deleteById
not perform exactly the same as my custom deleteByPid
method?