简体   繁体   中英

Check for foreign key constraint violation before delete

I'm trying to determine wether or not it is possible to delete an object from the repository. In other words: If a delete would result in a DataIntegrityViolationException or not. This is meant to hide the "Delete" button on the frontend, if a delete is not possible.

Example: I got classes A and B:

@Entity
public class A{
    @Id
    private UUID id;

    @Column
    private String name;

    @ManyToMany
    private Set<B> bs= new HashSet<>();

    //getter, setter, equals,...
}
@Entity
public class B{
    @Id
    private UUID id;

    @Column
    private String name;

    //getter, setter, equals,...
}

Now if I want to delete an object of B, which is in any A objects set, I will get a "DataIntegrityViolationException". Of course since the object is actively in use as a key.

I thought about checking A first, to see if there are any references and I can safely delete my B instance. But in practise this might be a bit tricky, since more than one class could use class B and the other classes would be added later by someone else, not familiar with the code. Also this...

aRepository.findAll(Example.of(new A(null, null, new HashSet<>(Array.asList(b))));

only delivered absolute trash as a result (>20+ objects for ab used nowhere).

A second thought was by just trying something like this:

    @Transactional //always roll back
    public void inUse(B b) throws TransacationException{
        bRepository.delete(composition);
        throw new TransacationException();
    }

and then checking it like this:

    public Boolean deleteAble(B b){
        try{
            inUse(b);
        } catch (DataIntegrityViolationException e){
            return false; // constraint violation --> in use!
        } catch (TransacationException e){
            return true;
        }
    }

Unfortunately none of these approaches seem to work. Have you got any idea on how to solve this problem?

Maybe you could make your @ManyToMany association bidirectional, like adding this to your class B :

@ManyToMany(mappedBy = "bs")
private Set<A> as = new HashSet<>();

Then it would be only like:

someB.getAs().isEmpty()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM