Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate mapping / 25 сообщений из 27, страница 1 из 2
22.09.2017, 17:31
    #39525080
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Всем привет.
Имеется вот такая объективная реальность, данная нам в ощущениях:

Структура БД:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
+-----------+        +-------------------+
|   USER    |        | USER_TO_USER_ROLE |        +----------------+
+-----------+        +-------------------+        |   USER_ROLE    |
| USER_ID   | <----> | USER_ID        PK |        +----------------+
| USER_NAME |        | USER_ROLE_ID   PK | <----> | USER_ROLE_ID   |
+-----------+        | IS_ACTUAL         |        | USER_ROLE_NAME |
                     +-------------------+        +----------------+

Классы:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
package example;

public class User {
    Long userId;
    String userName;
    Set<UserRole> userRoles;
}

public class UserRole {
    Long userRoleId;
    boolean actual;
    User user;
}

public class UserToUserRolePK {
    Long userId;
    Long userRoleId;
}



И маппинг:
Код: xml
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.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.1"
        xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd">

    <entity name="User" class="example.User" access="FIELD">
        <table name="USER"/>
        <attributes>
            <id name="userId">
                <column name="USER_ID" />
            </id>
            <basic name="userName">
                <column name="USER_NAME"/>
            </basic>
            <one-to-many name="userRoles" fetch="LAZY" target-entity="example.UserRole" orphan-removal="true" mapped-by="user">
                <cascade>
                    <cascade-all />
                </cascade>
            </one-to-many>
        </attributes>
    </entity>
    
    <entity name="UserRole" class="example.UserRole" access="FIELD">
        <table name="USER_TO_USER_ROLE"/>
        <id-class class="example.UserToUserRolePK" />
        <attributes>
            <id name="userRoleId">
                <column name="USER_ROLE_ID" />
            </id>
            <basic name="actual">
                <column name="IS_ACTUAL"/>
            </basic>
            <many-to-one name="user" id="true" target-entity="example.User" fetch="LAZY">
                <join-column name="USER_ID" referenced-column-name="USER_ID" />
            </many-to-one>
        </attributes>
    </entity>



Почему так сделано вопрос не стоит. Работает - не трогай. Но вот понадобилось в класс UserRole прокинуть поле USER_ROLE.USER_ROLE_NAME. Структуру БД менять нельзя, можно только маппинг крутить.

Попробовал через secondary table, но не получается увязать с составным ключом в USER_TO_USER_ROLE.
Только если убрать упоминание о составном ключе из маппинга.
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    <entity name="UserRole" class="example.UserRole" access="FIELD">
        <table name="USER_TO_USER_ROLE"/>
        <secondary-table name="USER_ROLE"/>
                <primary-key-join-column name="USER_ROLE_ID" referenced-column-name="USER_ROLE_ID"/>
        </secondary-table>
        <!--<id-class class="example.UserToUserRolePK" />-->
        <attributes>
            <id name="userRoleId">
                <column name="USER_ROLE_ID" />
            </id>
            <basic name="userRoleName">
                <column name="USER_ROLE_NAME" table="USER_ROLE"/>
            </basic>
            <basic name="actual">
                <column name="IS_ACTUAL"/>
            </basic>
            <!--<many-to-one name="user" id="true" target-entity="example.User" fetch="LAZY">-->
            <many-to-one name="user" target-entity="example.User" fetch="LAZY">
                <join-column name="USER_ID" referenced-column-name="USER_ID" />
            </many-to-one>
        </attributes>
    </entity>



Но что-то не нравится мне в таком костыле. Как можно(?) сделать правильно?
...
Рейтинг: 0 / 0
22.09.2017, 19:18
    #39525116
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим,
У вас в базе есть поле ИмяРоли. Почему в классе его нет?
...
Рейтинг: 0 / 0
22.09.2017, 19:23
    #39525118
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигримможно только маппинг крутить.
Ну и крути.
У тебя первый класс, вторая четверть Много ко Многим.
Убери только флаг актуальности. Тошнит от него и аноотации не в xml. Я лично плохо вижу в xml.
...
Рейтинг: 0 / 0
22.09.2017, 19:39
    #39525123
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Petro12313-й Пилигрим,
У вас в базе есть поле ИмяРоли. Почему в классе его нет?
Не стал приводить измененный вариант. Представим, что есть
Код: java
1.
2.
3.
4.
5.
6.
public class UserRole {
    Long userRoleId;
    String userRoleName;
    boolean actual;
    User user;
}
...
Рейтинг: 0 / 0
22.09.2017, 19:45
    #39525126
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Petro123Убери только флаг актуальности. Тошнит от него
Выпей таблетку и представь там любое другое поле
Petro123и аноотации не в xml. Я лично плохо вижу в xml.
Ну, ради тебя я весь legacy-проект на аннотации из xml переводить не буду.

Пример приведен намеренно до предела упрощенный, почти абстрактный. Смысл проблемы, что нужно смапить поля из разных таблиц: userRoleId и actual из USER_TO_USER_ROLE, а userRoleName из USER_ROLE, ну или userRoleId и userRoleName из USER_ROLE, а actual из USER_TO_USER_ROLE.
...
Рейтинг: 0 / 0
22.09.2017, 19:45
    #39525128
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримPetro12313-й Пилигрим,
У вас в базе есть поле ИмяРоли. Почему в классе его нет?
Не стал приводить измененный вариант. Представим, что есть
Код: java
1.
2.
3.
4.
5.
6.
public class UserRole {
    Long userRoleId;
    String userRoleName;
    boolean actual;
    User user;
}


Тогда не понял слово Прокинуть)
...
Рейтинг: 0 / 0
22.09.2017, 19:50
    #39525129
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримСмысл проблемы, что нужно смапить поля из разных таблиц: userRoleId и actual из USER_TO_USER_ROLE, а userRoleName из USER_ROLE, ну или userRoleId и userRoleName из USER_ROLE, а actual из USER_TO_USER_ROLE.
Без actual работает?
Зы. Таблетку выпил. Терплю и маппинг не читаю.
...
Рейтинг: 0 / 0
22.09.2017, 19:52
    #39525130
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Petro12313-й Пилигримпропущено...

Не стал приводить измененный вариант. Представим, что есть
Код: java
1.
2.
3.
4.
5.
6.
public class UserRole {
    Long userRoleId;
    String userRoleName;
    boolean actual;
    User user;
}


Тогда не понял слово Прокинуть)
Нужно правильно написать маппинг. Пока у меня получилось только если в маппинг не указывать что ключ составной.
...
Рейтинг: 0 / 0
22.09.2017, 19:54
    #39525131
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим UserRole прокинуть поле USER_ROLE.USER_ROLE_NAME.
И вот, получается, что в классе Роли поле имяРоли есть.
Удачи!
...
Рейтинг: 0 / 0
22.09.2017, 19:56
    #39525133
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Petro123Без actual работает?
Без него нет смысла работать.

Ещё раз: есть 2 значимых поля в разных таблицах. Их нужно свести в одну сущность
...
Рейтинг: 0 / 0
22.09.2017, 20:01
    #39525135
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримБез него нет смысла работать.
Ты хочешь, чтобы актуальность влияла на отношения тогда я пас.
Извиняй.
...
Рейтинг: 0 / 0
22.09.2017, 20:06
    #39525137
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримБез него нет смысла работать.
Off
Вообще, элементарно.
- все не актуальные записи удалить
- стандартный маппинг
- в гуи сделать галку актуальность через настройки и шаблоны ролей.
...
Рейтинг: 0 / 0
25.09.2017, 08:33
    #39525562
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
К сожалению, GUI менять нельзя, структуру и наполнение базы менять нельзя.

Если вас так смущает признак актуальности, представьте вместо него любой другой признак, имеющий значение только для пары. Ну, например, есть врач, есть виды приема, которые этот врач осуществляет, и есть стоимость конкретного вида приема у конкретного врача.
Код: plaintext
1.
2.
3.
4.
5.
6.
+-------------+        +--------------------+
|   DOCTOR    |        | DOCTOR_TO_REC_TYPE |        +----------------+
+-------------+        +--------------------+        | RECEPTION_TYPE |
| DOCTOR_ID   | <----> | DOCTOR_ID       PK |        +----------------+
| DOCTOR_NAME |        | REC_TYPE_ID     PK | <----> | REC_TYPE_ID    |
+-------------+        | COST               |        | REC_TYPE_NAME  |
                       +--------------------+        +----------------+
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
package example;

public class Doctor {
    Long doctorId;
    String doctorName;
    Set<ReceptionType> receptionTypes;
}

public class ReceptionType {
    Long recTypeId;
    String recTypeName;
    Double cost;
    Doctor doctor;
}

public class DoctorToRecTypePK {
    Long doctorId;
    Long recTypeId;
}


Код: xml
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.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.1"
        xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd">

    <entity name="Doctor" class="example.Doctor" access="FIELD">
        <table name="DOCTOR"/>
        <attributes>
            <id name="doctorId">
                <column name="DOCTOR_ID" />
            </id>
            <basic name="doctorName">
                <column name="DOCTOR_NAME"/>
            </basic>
            <one-to-many name="receptionTypes" fetch="LAZY" target-entity="example.ReceptionType" orphan-removal="true" mapped-by="user">
                <cascade>
                    <cascade-all />
                </cascade>
            </one-to-many>
        </attributes>
    </entity>
    
    <entity name="ReceptionType" class="example.ReceptionType" access="FIELD">
        <table name="DOCTOR_TO_REC_TYPE"/>
        <secondary-table name="RECEPTION_TYPE"/>
                <primary-key-join-column name="REC_TYPE_ID" referenced-column-name="REC_TYPE_ID"/>
        </secondary-table>
        <!--<id-class class="example.DoctorToRecTypePK" />-->
        <attributes>
            <id name="recTypeId">
                <column name="REC_TYPE_ID" />
            </id>
            <basic name="recTypeName">
                <column name="REC_TYPE_NAME" table="RECEPTION_TYPE"/>
            </basic>
            <basic name="cost">
                <column name="COST"/>
            </basic>
            <!--<many-to-one name="doctor" id="true" target-entity="example.Doctor" fetch="LAZY">-->
            <many-to-one name="doctor" target-entity="example.Doctor" fetch="LAZY">
                <join-column name="DOCTOR_ID" referenced-column-name="DOCTOR_ID" />
            </many-to-one>
        </attributes>
    </entity>



Это, опять же, абстрактный пример, наполненный для наглядности некой смысловой нагрузкой.
...
Рейтинг: 0 / 0
25.09.2017, 09:41
    #39525592
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим,
Ok
С врачом должно работать. Будет время посмотрю.
...
Рейтинг: 0 / 0
25.09.2017, 15:55
    #39525874
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Petro123Вообще, элементарно.
- все не актуальные записи удалить
Зачем. Может им надо знать кто кем был.
Может у них ротация кадров без повторов предусмотрена.
Типа сначчала Иванов был директором, потом стал говночистом. А Петров наоборот.
И HR помнят кто был кем, чтоб при следующей ротации их на старые места не поставить. :)

Просто у ТС объектная модель не соответствует реляционной. У него бывших директоров не бывает. Если кого увольняют, то вся роль становится не актуальной.
...
Рейтинг: 0 / 0
25.09.2017, 18:07
    #39525950
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Сергей АрсеньевМожет им надо знать кто кем был.
А какие роли были надо? А уволенные надо?
Пусть будут спрпвочные поля, а не значимые.
Т.е. проверяет не маппинг, а БЛ.
...
Рейтинг: 0 / 0
25.09.2017, 18:40
    #39525960
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Сергей Арсеньев,
Мысль такая, что к примеру, если в табле 20 записей и у 15 галка неАктуально, то при открытии сессии у Иванов в коллекции будет 20 ролей по маппингу.
А потом пусть List.where(isActual = true) если надо.
...
Рейтинг: 0 / 0
26.09.2017, 00:39
    #39526038
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим
Код: java
1.
2.
3.
4.
5.
public class ReceptionType {
    Long recTypeId;
    String recTypeName;
    Double cost;
    Doctor doctor;


не один доктор, а коллекция докторов.
Много-ко-многим это коллекции (много) с обоих сторон.
...
Рейтинг: 0 / 0
26.09.2017, 01:20
    #39526039
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим
Код: java
1.
2.
3.
4.
5.
public class ReceptionType {
    Long recTypeId;
    String recTypeName;
    Double cost;
    Doctor doctor;


у тебя cost находится в промежуточной табле. Значит и в классе это поле должно сидеть в
DOCTOR_TO_REC_TYPE.
...
Т.к. у тебя кроме связи двух полей добавилось поле cost, то тогда делаем среднюю таблу как полноценную сущность. Хоть с 50-тью полями.
Как то так.
...
Рейтинг: 0 / 0
26.09.2017, 08:25
    #39526076
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
[quot Petro123]13-й Пилигрим
Код: java
1.
2.
3.
4.
5.
public class ReceptionType {
    Long recTypeId;
    String recTypeName;
    Double cost;
    Doctor doctor;


не один доктор, а коллекция докторов.
Много-ко-многим это коллекции (много) с обоих сторон.
Нет, это именно конкретный доктор с конкретной стоимостью за конкретный вид приема. Т.е. у другого доктора этот же вид приема может иметь другую стоимость.
Petro123у тебя cost находится в промежуточной табле. Значит и в классе это поле должно сидеть в
DOCTOR_TO_REC_TYPE.
...
Т.к. у тебя кроме связи двух полей добавилось поле cost, то тогда делаем среднюю таблу как полноценную сущность. Хоть с 50-тью полями.
Как то так.
Другую таблу делать нельзя... Какая бы несовершенная архитектура ни была.

В общем, как я понял, в такой постановке (без изменения самой постановки) решение не находится.
...
Рейтинг: 0 / 0
26.09.2017, 08:34
    #39526077
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримНет, это именно конкретный доктор с конкретной стоимостью за конкретный вид приема. Т.е. у другого доктора этот же вид приема может иметь другую стоимость.
Напиши тут 5 строк с данными и пойшь

Что не может доктор находится в табле ВидПриёма.
Как и не может User быть в Roles.
Только list User.
Т.к. у роли много юзверей.
...
Рейтинг: 0 / 0
26.09.2017, 08:53
    #39526088
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й Пилигрим,
1 ый пример лучше был. Только заменить поле Актуальность на ДатуВставки.
Тогда 3 сущности и 3 класса.
Прокинуть нельзя т.к. конкретный ЮзерРоль будет в средней сущности ЮзерТоРолес
...
Рейтинг: 0 / 0
26.09.2017, 08:59
    #39526096
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримНет, это именно конкретный доктор с конкретной стоимостью за конкретный вид приема.
Почему он сидит в табли СправочникРабот?
Ведь "прокидывают" поле в другую сущность в виде list.
...
Рейтинг: 0 / 0
26.09.2017, 12:33
    #39526323
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
13-й ПилигримДругую таблу делать нельзя... Какая бы несовершенная архитектура ни была.
У тебя нет архитектуры. У тебя бардак.

В БД есть возможность, что пациент Иванов пришел ко врачу Сидорову и заплатил 100р. Потом пришел Петров и заплатил 200.
А в объектах у тебя врач Сидоров и 200 (ну или 100) и что ходили к нему и Иванов и Петров.

Как говорят в армии - пусть будет безобразно, но должно быть однообразно. :)
...
Рейтинг: 0 / 0
26.09.2017, 12:46
    #39526344
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate mapping
Сергей АрсеньевВ БД есть возможность, что пациент Иванов пришел ко врачу Сидорову и заплатил 100р. Потом пришел Петров и заплатил 200.

Шта?! Пациент Петров пришел к вчерашнему выпускнику Сидорову и заплатил 100р. Не понравилось. Пошел к профессору Преображенскому и заплатил 1000р. Пациент Петров, пройдя по тем же врачам, заплатит столько же сколько и Иванов.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate mapping / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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