powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate: Необычные связи. Можно и нужно ли так делать?
32 сообщений из 32, показаны все 2 страниц
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37888971
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день. Есть БД из трех таблиц:
Код: sql
1.
2.
3.
T1(id)
T2(id)
T3(id,ref_id,ref_type,value)


Для всех таблиц id - суррогатный первичный ключ. В таблице T3 ref_id ссылается на поля id таблицы T1 или T2. ref_type - обозначает, на какую именно таблицу ссылается ref_id. При этом T1 и Т2 отражают сущности предметной области, их тип (на который ссылается Т3.ref_type) известен только на уровне приложения, в таблицах (Т1, Т2) он не хранится. Т3 - не является сущностью, это своего рода результат деятельности. Пример: простейший учет невыходов на работу. Пусть Т1 отражает прогулы, Т2 - больничные. Пусть они оба содержат дату начала и окончания события, а в таблицу Т3 пишут количество дней прогула/больничного. Тогда Т3 позволит получить общее количество дней отсутствия на работе.
Вопросы: Можно ли такое поведение (получение сущностей Т1 и Т2 с коллекциями их записей из Т3 ) замапить аннотациями JPA/Hibernate? Какая альтернатива может быть такой схеме при условии сохранения функционала?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37888990
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
странная у вас и не нормализованая структура. но она легко исправляется введением дополнительноый таблицы T4 для хранения всех PK.

T1 и T2 имеют PK, который так же является FK на T4.
T3 ссылается на T4. Таким образом на ref_id можно смело навесить FK constraint.

Таким образом вы получите целостную структуру, которую сложно сломать, благодаря сильным FK констрейнтам.

Мапиться это всё в Hibernate через наследование и MappedSuperclass. Надо вообще точнее посмотреть способы маппинга.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889033
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, большое спасибо за ответ. О таком варианте я думал, в итоге я получу Т3 с FK на Т4 через ref_id, без использования doc_id. То есть фактически, буду иметь возможность по ссылке на экземпляр Т1 или Т2 вытянуть все связанные с ними записи из Т3. Это очень хорошо. Но, я буду лишен возможности анализировать саму Т3 на предмет того, к какому типу относятся записи в ней. Я не смогу сказать - эти записи класса Т2, вот эти - класса Т1. Или, на моем примере, не смогу отделить больничные от прогулов.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889039
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerBlazkowicz, большое спасибо за ответ. О таком варианте я думал, в итоге я получу Т3 с FK на Т4 через ref_id, без использования doc_id. То есть фактически, буду иметь возможность по ссылке на экземпляр Т1 или Т2 вытянуть все связанные с ними записи из Т3. Это очень хорошо. Но, я буду лишен возможности анализировать саму Т3 на предмет того, к какому типу относятся записи в ней. Я не смогу сказать - эти записи класса Т2, вот эти - класса Т1. Или, на моем примере, не смогу отделить больничные от прогулов.
В вашем случае ref_id может ссылаться на "прогул", в то время как ref_type будет "говорить" что это больничный. Кому вы будете верить в этой ситуации?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889050
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, согласен на все сто процентов, в моем случае сама база данных никак не в состоянии проконтролировать, что ref_id будет именно того типа, который мне нужен, поэтому эту ответственность придется переложить на уровень приложения. Только как?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889061
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно сделать эту колонку вычислимой так чтобы база ещё и кешировала значение.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889069
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, как это сделать?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889079
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerПусть Т1 отражает прогулы, Т2 - больничные. Пусть они оба содержат дату начала и окончания события, а в таблицу Т3 пишут количество дней прогула/больничного. Тогда Т3 позволит получить общее количество дней отсутствия на работе.
А зачем делать необычные связи?
У вас задача на нобелевскую?

Если через типы, то тогда

ОднаТаблица(ТипСобытия, ДатаНачала, ДатаОкончания)

Всё остальное вычисляется.
А вообще лучше от Сущности Документ идти - Приказ-О-прогуле и т.д.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889085
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerBlazkowicz, как это сделать?
Спросите в профильных форумах. У вас, вероятно, та самая единственная SQL база данных, которая без вариантов. Да?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889092
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, с одной таблицей я не выкручусь. Даже если пойду от сущности "Документ". Их может быть не 2 а 20, и все с разными полями, общие у них конечно будут, типа дата документа, комментарий, еще что-нибудь в этом духе. А относиться они могут при этом к одной области, и вычислять значения, которые мне нужно хранить в Т3 как им вздумается. Их объединяет не общая структура, а общий результат - который мне нужно хранить в Т3.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889096
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, у меня база с вариантами. Я ищу вариант, с которым мне будет удобнее работать, и который можно будет безболезненно расширить при появлении новых сущностей типа Т1 и Т2
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889107
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
ну дак нужно идти от простого к сложному. А не наоборот.
- вы привели вверху ТЗ на одну таблицу, а теперь говорите о 20 ТИПАХ документов.

Просто, есть 2 варианта проектирования:
- от ОРМ - Начинать с классов и хорошо ложится на Хибер
- от СУБД - Начинать с табличек РСУБД. Схема БД УЖЕ есть.

У вас какой?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889109
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerBlazkowicz, у меня база с вариантами. Я ищу вариант, с которым мне будет удобнее работать, и который можно будет безболезненно расширить при появлении новых сущностей типа Т1 и Т2
понятно.
Появление НОВОЙ СУЩНОСТИ в динамике после создания ИС - самое неблагодарное дело.
Это конструктор-фреймворк-ядро.
IMHO
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889113
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
давайте попробуем с другой строны.
Диаграмму классов для вашего случая.
А хранилище потом.
Напишите классы.
Удачи!
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889123
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, у меня от базы. От базы, которой еще нет. В моей предметной области происходят события, эти события регистрируются документами. То есть как минимум у меня будет по одной таблице на каждый вид регистрируемого события. Делать одну таблицу с типом события не могу, потому что у документов может быть сильно разная структура. Кроме собственно регистрации события, на основании данных документа будут произведены некоторые вычисления, и результаты вычислений мне нужно будет хранить в еще одной таблице. При этом туда свои вычисления могут складывать разные документы. Сколько их будет, я пока не знаю. Поэтому мне нужна ссылка на документ и на его тип в этой таблице. Еще один важный момент. Я хочу иметь возможность включать/выключать отражение вычислений документа. То есть его родную таблицу не трогаю, но при необходимости удаляю/записываю его вычисления в таблицу результатов вычислений. Отчеты я буду строить по таблице результатов, и никогда не буду трогать сами таблицы документов.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889181
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
ну.
А я ни разу не против.
- лучше идти не читсо от БД, а параллельно писать классы. Ты ведь с Хибером дружить хочешь? А его цель - классы.
- всё таки Первичен - ДОКУМЕНТ и он порождает событие? Тогда аналогия 1С. Приведи пример реальный.
- кто добавляет НОВЫЙ тип документа - Пользователь? Тогда должен быть класс - Менеджер документов.
- т.е. тип ИС - ДокументоОриентированная или Учётная?

и т.д.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889186
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если, а-ля 1С. То примерно так и будет.

Типы Документов. У них в полях значения. На кнопку - Провести - пишут в T3.
На кнопку Убрать проведение - очищают её от себя.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889252
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, первичен документ, эта идея именно из 1С, уж очень мне понравились их мысли по поводу регистров сведений/накопления. С хибером дружить хочу, попробовал зайти со стороны классов. То есть позволить хиберу создать схему базы данных по моим аннотированным классам (Документы разные - то что они навычисляли имеет одинаковый формат). Вот классы (геттеры, сеттеры, методы опущены):

Код: 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.
@Entity
public class Reg implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Basic(optional = false)
    @Column(name = "val")
    private int val;
}

@Entity
public class Doc1 implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToMany
    private Set<Reg> regSet;
      }
    
@Entity
public class Doc2 implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToMany
    private Set<Reg> regSet;
      }



По такому определению хибер генерирует схему, привязывая каждый Doc к Reg через вспомогательную таблицу. На уровне классов я конечно могу найти соответствие между doc и его Reg. Но отчеты я буду строить не вытаскивая из базы каждую строчку в новый объект, а обычными запросами и обработкой результата. И там опять же я не имею в таблице Reg ссылки на тип документа, который породил запись. В одинэсе такая возможность есть.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889259
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
это замечательно, что ты так быстро и наглядно всё провернул.
А вот идею с reg я не просекаю. Тут надо к 1С никам.

1.
По мне проще что у тебя было.
2.
Тебя устраивает, что приновом DOC2 тебе нужно будет апгрейдить систему. Т.е. это делает не заказчик.
Т.к. слишком быстро ты всё на свою табличку фактов идёшь.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889265
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123, тут еще идеологический вопрос. Все-таки документы (Т1,Т2 или Doc1, Doc2) это сущности, а их результаты (T3, Reg) - нет. А по классам получается что сущности и те и другие. Может у хибернейта есть что-нибудь на этот счет?
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889293
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
Сущность - это объект значимый для бизнеса.
Т.е. строка в Т3 - вполне ей может быть (как объект-"Событие")
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37889297
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно не делать сущностями, но тогда это как раз твоя схема выше и дописать процедуры - "Провести" "УбратьПровести" - руками.
Т.е. это будет Сервисный слой бизнес-логики
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890129
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, подумал присмотреться к этому поближе:авторстранная у вас и не нормализованая структура. но она легко исправляется введением дополнительноый таблицы T4 для хранения всех PK.

T1 и T2 имеют PK, который так же является FK на T4.
T3 ссылается на T4. Таким образом на ref_id можно смело навесить FK constraint.

Таким образом вы получите целостную структуру, которую сложно сломать, благодаря сильным FK констрейнтам.

В этом случае констрейнты слишком сильные, или я чего-то недопонял. Если у Т4 (doc_reg на схеме) будут FK и на T1(Doc1) и на T2(Doc2), то в нее можно будет писать только Id, которые есть сразу в обеих таблицах T1 и T2. То есть если у меня в T1 есть айди (1,2,3) а в T2(4,5,6), то я не смогу в T4 записать ни то ни другое.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890134
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerВ этом случае констрейнты слишком сильные, или я чего-то недопонял. Если у Т4 (doc_reg на схеме) будут FK и на T1(Doc1) и на T2(Doc2)
Если бы так можно было, то не нужна была бы дополнительная таблица. Обошлись бы тремя как в вашем первом варианте. FK должен быть с другой стороны.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890148
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, Я в таком случае совершенно запутался. Если FK должен быть с другой стороны, то doc_id В Т4(doc_reg) должно быть уникально, а оно не может, потому что Т1 и Т2 могут быть одинаковые идентификаторы.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890153
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerдолжно быть уникально, а оно не может, потому что Т1 и Т2 могут быть одинаковые идентификаторы.
Это не обязательно. Нужно просто INSERT реализовать так, чтобы после вставки в T4, тот же самый ID использовался в T1 или T2. В них не будет автоинкремента. Они просто будут использовать значение PK из T4 для собственнй PK+FK колонки. Hibernate такое умеет.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890163
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, может тогда лучше взять sequence и назначить его для генерации id T1 и T2 и вообще не использовать T4? У меня Postgres, вроде бы он такое позволяет
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890166
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerBlazkowicz, может тогда лучше взять sequence и назначить его для генерации id T1 и T2 и вообще не использовать T4? У меня Postgres, вроде бы он такое позволяет
Тогда у вас не будет FK констрейнта в T3.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890178
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, шах и мат. Если приходится делать такое на несложной в принципе базе:
авторНужно просто INSERT реализовать так, чтобы после вставки в T4, тот же самый ID использовался в T1 или T2. В них не будет автоинкремента. Они просто будут использовать значение PK из T4 для собственнй PK+FK колонки. Hibernate такое умеет.
значит с базой что-то явно не в порядке, буду думать что-то более вменяемое. Хибернейт наверняка умеет, но я еще не скоро научусь делать такое. Очередной, и боюсь не последний раз, благодарю за консультацию.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890182
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerBlazkowicz, шах и мат. Если приходится делать такое на несложной в принципе базе:
значит с базой что-то явно не в порядке, буду думать что-то более вменяемое. Хибернейт наверняка умеет, но я еще не скоро научусь делать такое. Очередной, и боюсь не последний раз, благодарю за консультацию.
Hibernate много чего умеет. Но безотносительно его, базу данных стоит проектировать так, чтобы гарантировать целостность данных.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890198
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, да, я писал уже про рыбку и сидение. Хочу возможности как в 1с (документ - регистр), но там даже не пахнет целостностью на уровне СУБД. А чтобы и функциональность получить ту же и согласованную базу без извращений и опирания на возможности конкретно хибернейта, буду "экскрементировать" дальше.
...
Рейтинг: 0 / 0
Hibernate: Необычные связи. Можно и нужно ли так делать?
    #37890244
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,
чтобы гарантировать на уровне СУБД. Надо не сливать данные от разной БЛ-сущностей в одну таблицу.
Тогда вьюшка объединяет и суммирует в представлении-слое.
Но, понятно, что при использовании ОРМ (Хибер), ни о каком сильном контроле говорить не приходится.
Контролирует Хибер.
-------
С другой стороны, если у Вас есть Факты в таблице Т4 за прошлый год. И вы вдруг решили удалить Документы их родившие.
То опять Вам решать как это будет происходить.
В 1С это в БЛ сервисном проверяются все связи и даётся разрешение всё удалить.....
...
Т.е. делается по разному - делайте как БЫСТРО-ПРОСТО-УДОБНО.
Всё расно потом переделывать))) шутка))
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate: Необычные связи. Можно и нужно ли так делать?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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