Skip to content

Spring Data JPA: delete OneToMany child without going through the parent

My application has a Project entity that has set of Resource entities like this:

@Entity
public class Project {
    @OrderBy("name ASC")
    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = false)
    @Column(name = "resources")
    private Set<Resource> resources;
}

The Resource entities may be referenced by several projects, and I’m wondering how to delete a Resource from the database easily without first removing it from the resources list of each parent Project. Trying to delete the resource directly using the repository’s deleteById method results in a foreign key constraint violation if the Resouce in question is referenced in one or more projects.

Edit: the database schema has a table called project_resources which maps resource IDs to project IDs.

Answer

Based on your question it seems there is a many-to-many relation between the Project and Resource tables. And based on your entity I assume on the database level there is no join table, but every Project has a Resource reference (FK) and vica versa.

Assuming this if you want to delete a resource, first you have to delete all references to it. You could execute a native update like this:

update Project set resource_id = null where resource_id = :resourceIdToBeDeleted;

After this, you can delete the resource.


If my assumption is wrong, and you still have a join table, then you have to delete rows from the join table. Something like this:

delete from Project2Resource where resource_id = resourceIdToBeDeleted;

After this, you can delete the resource.

In this scenario you could also model your join table with an entity, like Project2Resource and delete these entities with spring query method (deleteByResourceId(long id)) before the resource deletion.