1

I'm working on some legacy code so unfortunately I'm unable to answer why the code has been designed as is. There are two entities: Inbox and Upload.

public class Upload {

    // other properties...

    @ManyToOne(cascade = PERSIST)
    @JoinColumn(name = "inbox_id", nullable = false)
    private Inbox inbox;
}

public class Inbox {

    // other properties...
}

Inbox does not have any relationship to Upload. Only Upload references the Inbox via the inbox_id.

Now I'd ilke to delete an Upload item like this:

public void deleteUpload(long uploadId) {
  final Upload upload = uploadRepo.findById(uploadId).orElseThrow(EntityNotFoundException::new);
  uploadRepo.delete(upload);
}

This works fine. However, I'd also like to delete the corresponding Inbox but I have no idea how to do that. My current approach looks like this, but this does not delete in Inbox item.

public void deleteUpload(long uploadId) {
  final Upload upload = uploadRepo.findById(uploadId).orElseThrow(EntityNotFoundException::new);
  uploadRepo.delete(upload);
  inboxRepo.deleteById(upload.getInbox().getId());
}

Update 1

I tried @ManyToOne(cascade = {PERSIST, REMOVE}) but this leaves the Inbox remain in the database.

What puzzles me even more: Setting spring.jpa.show-sql=true doesn't show any delete statement for for the Inbox entity.


Update 2

In this similar SO question I found that the following actually works:

@Modifying
@Query("delete from Innox i where i.id = ?1")
void delete(long id);

Although I feel that this is not "the" way to do it.

Robert Strauch
  • 12,055
  • 24
  • 120
  • 192
  • @Jens I edited my answer. Already tried the `REMOVE` cascade but it has no effect. – Robert Strauch May 04 '21 at 13:02
  • Can you set a breakpoint just before you delete the `upload` object? Is the `Inbox` reference present? Maybe it is not due to lazy loading? – Wim Deblauwe May 04 '21 at 13:50
  • Does this answer your question? [JPA OneToMany not deleting child](https://stackoverflow.com/questions/2011519/jpa-onetomany-not-deleting-child) – xerx593 May 04 '21 at 13:57
  • What happens when you call `inboxRepo.deleteById(upload.getInbox().getId())`? – crizzis May 04 '21 at 18:47
  • @crizzis It depends on the cascade. Without `REMOVE` cascade, the `Inbox` item still exists in the database. When adding the `REMOVE` cascade: `org.springframework.dao.EmptyResultDataAccessException: No class ...Inbox entity with id 170 exists!` So it seems as if the cascade attempts to delete it. But then removing the `deleteById` statement, the item isn't actually deleted. – Robert Strauch May 04 '21 at 18:58

1 Answers1

0

Basically, the Parent can remove it's child not the reverse. In this context also Inbox is the owner where as Upload is dependent on Inbox. If we take into account of Parent and Child then if there is no child parent can still exist but if there is no parent then child can not exist. Same rules applies in this context so you have to follow any of the alternatives that you identified.

msucil
  • 806
  • 1
  • 8
  • 15