Связь «многие ко многим» с составными ключами в Hibernate

Есть ли способ использовать аннотацию @JoinTable, соединяющую каждую таблицу двумя полями? Вот примеры таблиц:

+----------------+  +----------------------------------+  +----------------+      
| example_table  |  | example_table_to_some_type_table |  | some_type_table|
+----------------+  +----------------------------------+  +----------------+   
|example_table_id|  |example_table_id                  |  |some_type_id    |
|another_id      |  |some_type_id                      |  |another_id      |
|...             |  |another_id                        |  |...             |
|other columns   |  +----------------------------------+  |other columns   |
|...             |                                        |...             | 
+----------------+                                        +----------------+

Для случая «многие к одному» это будет выглядеть так:

@ManyToOne
@JoinColumns({ @JoinColumn(name = "some_type_id", 
    referencedColumnName = "some_type_id", 
    insertable = false, updatable = false),
               @JoinColumn(name = "another_id", 
    referencedColumnName = "another_id", 
    insertable = false, updatable = false) })
private SomeType someType;

Но как насчет отношений многие ко многим? Я пробовал следующее, и это не сработало:

@ManyToMany(targetEntity = SomeType.class)
@JoinTable(name = "example_table_to_some_type_table", 
    joinColumns = { @JoinColumn(name = "example_table_id"),  
                    @JoinColumn(name = "another_id") }, 
    inverseJoinColumns = { 
                    @JoinColumn(name = "some_type_id"),  
                    @JoinColumn(name = "another_id") })
private Set<SomeType> someTypeSet;

Я получил следующую ошибку:

Repeated column in mapping for collection: com.package.name.Example.someTypeSet column: another_id

На что я должен обратить внимание и какая часть этого сопоставления неверна? Заранее спасибо.


person John Doe    schedule 08.02.2013    source источник


Ответы (1)


В вашей таблице соединений должно быть 4 столбца. 2 для ссылки на столбцы PK example_table и 2 других для ссылки на столбцы PK some_type_table.

Так должно выглядеть

+----------------+  +----------------------------------+  +----------------+      
| example_table  |  | example_table_to_some_type_table |  | some_type_table|
+----------------+  +----------------------------------+  +----------------+   
|example_table_id|  |example_table_id                  |  |some_type_id    |
|another_id      |  |example_table_another_id          |  |another_id      |
|...             |  |some_type_id                      |  |...             |
|                |  |some_type_table_another_id        |  |                |
|other columns   |  +----------------------------------+  |other columns   |
|...             |                                        |...             | 
+----------------+                                        +----------------+
person JB Nizet    schedule 08.02.2013
comment
Спасибо за ответ. Не могли бы вы объяснить, почему мне нужно 4 столбца? 2-й и 4-й в вашем примере будут содержать одинаковые значения. И должен ли @JoinTable выглядеть почти так же, как тот, который я написал для этого случая, или это совершенно неправильно? - person John Doe; 08.02.2013
comment
Нет, они не будут. У вас есть строка в левой таблице с идентификатором [A, B] и строка в правой таблице с идентификатором [C, D]. Таким образом, чтобы иметь возможность сослаться на эти две строки, вам нужны A, B, C и D. Ваше определение таблицы соединений было бы в порядке, если бы вы не повторяли один и тот же столбец дважды. - person JB Nizet; 08.02.2013
comment
Я понимаю вашу точку зрения, и эта таблица на самом деле может работать, но в моем случае действительно есть [A,B] и [C,B] (ну, я не разрабатывал эти предварительные условия, просто нужно с ними работать). Поэтому, даже если это сработает, я бы дублировал данные. Что вы думаете об этой ситуации в целом? - person John Doe; 08.02.2013
comment
Если вы не можете гарантировать, что все строки в обеих таблицах всегда имеют одно и то же значение в столбце other_id (в этом случае этот столбец совершенно не нужен), вам потребуется 4 столбца в вашей таблице соединений. - person JB Nizet; 08.02.2013