Stefano Sambruna
Stefano Sambruna

Reputation: 797

How to delete an enitity with many bidirectional relationships

I have an entity with many relationship and even if I try to delete it, I keep find it inside the database.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class FatherObject {

    @Id
    private String id;

    @OneToOne(mappedBy = "fatherObject", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false, orphanRemoval = true)
    private ObjectX objectX;

}



@Entity
public class MainObject extends FatherObject {

    private String attr1;

    @OneToMany(mappedBy = "mainObject", cascade = CascadeType.ALL)
    private List<ObjectA> objectAList = new ArrayList<>();

    @OneToMany(mappedBy = "mainObject", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ObjectB> objectBList = new ArrayList<>();

    @OneToOne
    @JoinColumn(name="object_c_id")
    private ObjectC objectC;

    @OneToMany(mappedBy="mainObject", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<ObjectD> objectDList;

    @OneToMany(mappedBy="mainObject", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ObjectE> objectEList = new ArrayList<>();


    @OneToMany(mappedBy="mainObject", cascade = CascadeType.ALL)
    @JsonIgnore
    private List<ObjectF> objectFList = new ArrayList<>();


}


public interface MainObjectRepository extends JpaRepository<MainObject, String> {

}

The object I'm trying to delete is of type MaibObject and as you can see it has many relationships with other entities. And these entities have other relatioships with other entities.

I have tried everything but nothing works. I tried to set all the attributes to null and save then delete the object (because as I understood right orphanRemoval=true delete automatically all the children that are not pointed anymore by the parent). I've tried to delete the object by id, by the object. Nothing works. I do not know what's the recommended process to follow in order to delete an entity of this size. Any idea?

This is the last approach I used. I know it's wrong but I don't know what else to do:

  @Override
    public void deleteById(String mainObjectId){
        MainObject mainObject = getById(mainObjectId);

        mainObjectId.setObjectA(null);
        mainObjectId.setObjectB(null);
        mainObjectId.setObjectC(null);
        mainObjectId.setObjectD(null);
        mainObjectId.setObjectE(null);
        mainObjectId.setObjectF(null);

        mainObjectRepository.save(shop);
        mainObjectRepository.deleteById(shopId);
    }

[EDIT 1]

I would like all the other objects to be deleted with the parent object, except for the objectC which I want it to remain untouched.

[EDIT 2]

Thanks to @JB Nizet I found out that I wasn't breaking a relationship which was keeping alive the MainObject that I was trying to delete.

By setting the MainObject attribute inside ObjectC as null and then save the changes, the mainObject and all its attributes get deleted.

ObjectC objectC = mainIbject.getObjectC();
objectC.setMainObject(null);
objectCRepository.save(objectC);

And objectCRepository is:

@Repository
public interface ObjectCRepository extends JpaRepository<ObjectC, Long> {

}

Is there another way to do that or this is the recommended way?

Upvotes: 1

Views: 80

Answers (1)

JB Nizet
JB Nizet

Reputation: 692121

All your associations except the one with objectC have cascade=ALL. So if you delete the main object, the objects that are in objectAList, objectBList, etc. will be deleted too. Setting the lists to null prevents Hibernate to cascade the delete to these other objects. Don't do that.

The objectC is linked with a OneToOne, and the owner side is C. And you want C to stay there. But it can't possibly reference the main object anymore since you want to delete it. So you need to remove the link between C and the main object.

So you need

mainObject.getObjectC().setMainObject(null);
mainObjectRepository.delete(mainObject);

This of course assumes that proper cascading is configured in the linked entities too, and that they're not, themselves, referenced by other entities that are not deleted.

Upvotes: 1

Related Questions