Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром / 12 сообщений из 12, страница 1 из 1
26.09.2013, 12:37:44
    #38408258
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
Есть отношение препод - студент
многие ко многим.

соответственно в базе 3 таблицы
препод
препод_студент
студент

Если что, препод - owner.

Вопрос - как настроить маппинг так, чтобы при удалении студента - все его упоминания из промежуточной таблицы удалялись, НО преподы не удалялись из базы?
Если сделать каскад remove у студента - преподы тоже удаляются.
...
Рейтинг: 0 / 0
26.09.2013, 13:07:48
    #38408308
cdtyjv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
...
Рейтинг: 0 / 0
26.09.2013, 13:16:23
    #38408334
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
cdtyjv,

Из прочитанного понял(и проверил), что со стороны owner это работает...

а можно это как - то с двух сторон сделать?
...
Рейтинг: 0 / 0
26.09.2013, 13:23:17
    #38408351
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
Скорее всего, в данном сценарии каскады не нужны
Вот рекомендации из раздела Transitive persistence документации
• It does not usually make sense to enable cascade on a many-to-one or many-to-many association. In fact the @ManyToOne and @ManyToMany don't even offer a orphanRemoval attribute. Cascading is often useful for one-to-one and one-to-many associations.
• If the child object's lifespan is bounded by the lifespan of the parent object, make it a life cycle object by specifying cascade="all,deleteorphan"(@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)).
• Otherwise, you might not need cascade at all. But if you think that you will often be working with the parent and children together in the same transaction, and you want to save yourself some typing, consider using cascade="persist,merge,save-update".
То есть, если редактируя преподавателя, нужно не только "подключать", но и редактировать и создавать студентов, то со стороны преподавателя понадобится PERSISTS, MERGE.
А если просто подключать/отключать студентов (которых редактируют где-то в другом месте), то каскады не нужны.
Со стороны студента каскады не нужны.

Я лично предпочитаю для ManyToMany каскады не использовать
...
Рейтинг: 0 / 0
26.09.2013, 13:29:55
    #38408364
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
ivanra,

а если мне с любой стороны надо так:
при удалении студента/препода удалялся студент/препод и данные из промежуточной таблицы.
просто у меня сейчас так:

Если удалять препода, то всё работает так, как я и хочу, а со стороны студенты вываливается эксепшн о том, что
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Конфликт инструкции DELETE с ограничением REFERENCE
Код: java
1.
"FK_63a66b22ace64374a874912be64". Конфликт произошел в базе данных "ForHiberTest", таблица "dbo.prepod_Student", column 'students_id'.



маппинг:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
@Entity
@Table(name = "prepod")
public class Prepod {

    private Long id;
    private String name;
    @Column
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    List<Student> students = new ArrayList<Student>();

    @ManyToMany(fetch=FetchType.EAGER)
    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    public Long getId() {
        return id;
    }

    public void setId(Long i) {
        id = i;
    }
}


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
@Entity
@Table(name = "Student")
public class Student {

    private Long id;
    private String name;
    private Long age;
    private List<Prepod> prepods = new ArrayList<Prepod>();

    @ManyToMany(mappedBy = "students",fetch=FetchType.EAGER)
    public List<Prepod> getPrepods() {
        return prepods;
    }

    public void setPrepods(List<Prepod> prepods) {
        this.prepods = prepods;
    }

    public Student() {
        name = null;
    }

    public Student(Student s) {
        name = s.getName();
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    public Long getId() {
        return id;
    }

    @Column(name = "name")
    public String getName() {
        return name;
    }

    @Column(name = "age")
    public Long getAge() {
        return age;
    }

    public void setId(Long i) {
        id = i;
    }

    public void setName(String s) {
        name = s;
    }

    public void setAge(Long age) {
        this.age = age;
    }
}
...
Рейтинг: 0 / 0
26.09.2013, 13:43:33
    #38408396
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
redwhite90а можно это как - то с двух сторон сделать?
какой в этом смысл?
Академический?
...
Рейтинг: 0 / 0
26.09.2013, 14:05:15
    #38408445
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
redwhite90,
это известная особенность хибернейта: действия с коллекцией с инверсной стороны игнорируются. даже если написать
Код: java
1.
student.getPrepods().clear();

- ничего не произойдет, пока с "хозяйской" стороны не будет зеркального удаления. Приходится это учитывать и дублироваить с 2 сторон, чтобы наверняка. Как выариант - добавить серверный каскад на удаление, либо SQLQuery c delete-ом
...
Рейтинг: 0 / 0
26.09.2013, 15:07:51
    #38408557
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
Petro123redwhite90а можно это как - то с двух сторон сделать?
какой в этом смысл?
Академический?
это удобно имхо.
...
Рейтинг: 0 / 0
26.09.2013, 15:09:27
    #38408560
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
ivanraredwhite90,
это известная особенность хибернейта: действия с коллекцией с инверсной стороны игнорируются. даже если написать
Код: java
1.
student.getPrepods().clear();

- ничего не произойдет, пока с "хозяйской" стороны не будет зеркального удаления. Приходится это учитывать и дублироваить с 2 сторон, чтобы наверняка. Как выариант - добавить серверный каскад на удаление, либо SQLQuery c delete-ом

под серверным каскадом понимаете залезть руками на базу и добавить каскад?
...
Рейтинг: 0 / 0
26.09.2013, 15:37:18
    #38408592
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
redwhite90,
да, если sql сервер поддерживает каскадное удаление, то на таблицу связей на внешние ключи можно добавить ON DELETE CASCADE. Это то место, где hbm2ddl из-за своей универсальности ничего сделать не может.
Еще в хибернейте есть аннотация @Cascade, но для many-to-many она не работает
...
Рейтинг: 0 / 0
26.09.2013, 15:41:24
    #38408598
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
ivanraда, если sql сервер поддерживает каскадное удаление, то на таблицу связей на внешние ключи можно добавить ON DELETE CASCADE. Это то место, где hbm2ddl из-за своей универсальности ничего сделать не может.

И как обнавлять кеш второго уровня, когда каскад на уровне базы срабатывает?
...
Рейтинг: 0 / 0
26.09.2013, 16:23:23
    #38408655
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром
ivanraredwhite90,
да, если sql сервер поддерживает каскадное удаление, то на таблицу связей на внешние ключи можно добавить ON DELETE CASCADE. Это то место, где hbm2ddl из-за своей универсальности ничего сделать не может.
Еще в хибернейте есть аннотация @Cascade, но для many-to-many она не работает

Ок. буду знать. Я думал хибернейт такое должен уметь)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / hibernate. как в отношении многие-ко-многим настроить каскад между крайней таблицей и пром / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]