Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate. Связь many-to-many, отразить в TreeMap 
:(
    Опции темы
Shaggie
Дата 27.6.2007, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: 2
Всего: 72



Существует БД:

Код

CREATE TABLE cd (
cd_id INT PRIMARY KEY,
cd_name VARCHAR(255)
);

CREATE TABLE cd_style (
cd_id INT REFERENCES cd,
st_id INT REFERENCES style,
UNIQUE(cd_id, st_id)
);

CREATE TABLE style (
st_id INT PRIMARY KEY,
st_name VARCHAR(255)
);


Связь между таблицами cd и style осуществляется по принципу many-to-many, для чего существует сводная таблица cd_style.

Маппинг таблицы style:
Код

<class name="Style" table="style">
    <id name="id" column="st_id">
        <generator class="native"/>
    </id>
    <property name="name" column="st_name"/>
<class/>


Маппинг таблицы cd:
Код

<class name="Cd" table="cd">
    <id name="id" column="cd_id">
        <generator class="native"/>
    </id>
    <property name="name" column="cd_name"/>

    <set name="styles" table="cd_style">
        <key column="cs_cd"/>
        <many-to-many column="cs_style" class="db.Style"/>
    </set>
<class/>

Всё работает, в программе после вызова Cd.getStyles() генерится собственный сет объектов Style. Это нормально.

Но неэффективно с точки зрения логики программы. Гораздо правильнее было бы использовать коллекцию TreeMap. Но я не могу написать маппинг! Кто-нибудь сталкивался с необходимостью создавать мап объектов? В моём примере ключом, по идее, должен оказаться INT PRIMARY KEY таблицы style, а значением - соответствующий объект Style.

Возможные варианты:
Код

    <map name="styles" table="cd_style">
        <key column="cs_cd"/>
        <map-key ... /> <!--  ??? что написать ??? -->
        <many-to-many column="cs_style" class="db.Style"/>
    </map>

<!-- либо -->

    <map name="styles" table="cd_style">
        <key column="cs_cd"/>
        <map-key-many-to-many column="cs_style" class="db.Style"/>
        <element type="Style"/>
<!-- Если не указать в теге element параметр column, то выдаёт ошибку парсинга и требует его написать.
А если параметр существует, например, column="st_id", ругается: в указанной колонке НЕ тип Style -->
    </map>

Уже голова пухнет, но ответа так и не нашёл. Если можете - помогите, пожалуйста!


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
Shaggie
Дата 4.7.2007, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: 2
Всего: 72



Спасибо powerOn, который запостил в одном из обсуждений ссылку на http://www.java2s.com. Там я нашёл вариант решения проблемы, но он меня не очень устроил.

Как вы могли заметить, в элементе Map должно быть ещё три элемента, причём у каждого необходимо указать колонку из таблицы, с которой делается маппинг. То есть в промежуточной таблице должно быть ТРИ колонки! С одной стороны, это непорядок. С другой, тогда всё действительно работает.

В результате промежуточная таблица в базе выглядит так:
Код

CREATE TABLE cd_style (
    cd_id INT,
    st_key INT,
    st_id INT
);


а мап маппинга (извините... слова почти одинаковые, а понятия разные) таблицы cd так:
Код

    <map name="styles" table="cd_style">
        <key column="cd_id"/>
        <map-key column="st_key" type="java.lang.Integer"/>
        <many-to-many column="st_id" class="db.Style"/>
    </map>


Необходимые пояснения.
Число cd_id - это тот объект Cd, у которого будет свой мап объектов Style.
Число st_key - это объект типа Integer, который будет ключом (key) к для каждого Style в мапе.
Число st_id - это указатель на тот объект Style, который будет значением (value) в мапе.

Теперь после вызова Cd.getStyles() генерится собственный мап объектов Style, и это есть как раз то, что мне было нужно.

НО!

Появляются определённые издержки. Теперь запрос SELECT * FROM cd_style; вернёт такое вот чудо:

 cd_id | st_key | st_id
------------------------
     1 |      1 |     1
     1 |      3 |     3
     2 |      1 |     1
     2 |      6 |     6
     2 |      7 |     7

В результате таблица распухает на треть безо всякой пользы для цивилизации. Налицо подгон базы под hibernate, а ведь по идее он должен работать с тем, что дают, и уж тем более не ломать нормализацию... Однако повторюсь, что сохранять зависимость many-to-many наиболее эффективно всё-таки в мапе.

Поэтому тема остаётся открытой. Есть ли способы замапить связь, используя только ДВЕ колонки в промежуточной таблице?


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0401 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.