Порядок запросов на удаление Hibernate - PullRequest
4 голосов
/ 04 июня 2009

Вот моя модель данных (упрощенная),

public class AddressBook {
    private List<Group> groups = new ArrayList<Group>();
    private List<People> peoples = new ArrayList<People>();

    @OneToMany(mappedBy = "addressbook", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    public List<Group> getGroups() {
        return groups;
    }

    @OneToMany(mappedBy = "addressbook", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    public List<People> getPeoples() {
        return peoples;
    }
}


public class Group {
    private AddressBook addressBook;


    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    public void setAddressBook(AddressBook addressBook) {
        this.addressBook = addressBook;
    }
}

public class People {
    private AddressBook addressBook;
    private Group group;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    public AddressBook getAddressBook() {
        return addressBook;
    }
    public Group getGroup() {
        return group;
    }
}

Я хочу удалить полную группу из моей адресной книги и всех людей, принадлежащих к этой группе. Поэтому я делаю что-то вроде:

adressBook.getPeople().removeAll(peopleBelongingToGroupA);
adressBook.getGroups().remove(groupA);

Но когда моя транзакция зафиксирована, Hibernate делает первым:

delete from groups where groupName='groupA';

Вместо того, чтобы сначала удалять людей. Это приводит к нарушению моего ограничения FOREIGN_KEY между людьми и группой.

Есть ли способ сообщить hibernate об удалении сначала людей, а затем групп? Есть ли в моей модели недостаток?

Ответы [ 3 ]

2 голосов
/ 04 июня 2009

Вы пытались поставить настройку каскада для каждого @ManyToOne. Вы только указали, во многих отношениях, каскадное удаление в адресной книге. Я считаю, что это свойство для каждой ассоциации.

Спецификация EJB3.0 стоит того, чтобы иметь в виду при написании этих бинов. Смотри http://jcp.org/en/jsr/detail?id=220

Обновление: При повторном чтении вашей модели данных здесь могут отсутствовать аннотации к людям, которые бы объясняли поведение. У вас есть каскад, установленный на связь с людьми-> группой? Это объясняет, почему первый оператор должен начинаться с попытки удаления группы. Предположительно, вам нужна аннотация для групп людей, которые не каскадируются?

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

есть 2 варианта

1) вызов флеша перед вторым удалением

2) добавьте «каскад» к вашим сопоставлениям: т.е. Удаление группы также приведет к удалению членов группы.

0 голосов
/ 04 июня 2009

Вы можете сделать это как две транзакции или использовать каскад = удалить, как кто-то упоминал. На самом деле, вы, вероятно, хотите удалить сирот, которые выполняют каскадное удаление, но удаляют «Человека» только в том случае, если они полностью осиротели. Это делает 2 хорошие вещи:

1) Все, что вы делаете, это удаляете группу, и она автоматически удаляет дочерние элементы (при условии, что ваши сопоставления настроены правильно). 2) Если Person может принадлежать более чем к одной группе, он будет удалять этот дочерний объект Person только в том случае, если он потерян, то есть ни одна группа не ссылается на него.

Эта 2-я часть имеет большое значение, если у дочернего объекта (в данном случае Person) может быть несколько родителей, и поэтому дочерний объект не должен быть удален, если не удалены все родительские отношения.

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