Проверьте на наличие ограничений внешнего ключа перед удалением - PullRequest
0 голосов
/ 04 июня 2019

Я пытаюсь определить, возможно ли удалить объект из хранилища.Другими словами: если удаление приведет к исключению DataIntegrityViolationException или нет.Это означает, что кнопка «Удалить» на веб-интерфейсе скрыта, если удаление невозможно.

Пример: я получил классы А и В:

@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,...
}

Теперь, еслиЯ хочу удалить объект B, который находится в любом наборе объектов A, я получу «DataIntegrityViolationException».Конечно, поскольку объект активно используется в качестве ключа.

Сначала я подумал о проверке A, чтобы выяснить, есть ли какие-либо ссылки, и я могу безопасно удалить свой экземпляр B.Но на практике это может быть немного сложно, так как класс B может использовать более одного класса, а другие классы будут добавлены позже кем-то другим, не знакомым с кодом.Кроме того, это ...

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

в результате доставляло только абсолютный мусор (> 20+ объектов для ab нигде не использовалось).

Вторая мысль была при попытке что-то вроде этого:

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

и затем проверяем это так:

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

К сожалению, ни один из этих подходов не работает.У вас есть идеи, как решить эту проблему?

1 Ответ

1 голос
/ 04 июня 2019

Может быть, вы могли бы сделать свою @ManyToMany ассоциацию двунаправленной, например, добавив ее в свой класс B:

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

Тогда это будет только как:

someB.getAs().isEmpty()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...