Здравствуйте, IT, Вы писали:
IT>Как я понял, про Linq в NH пока лучше помолчать. Если так, то чем HQL лучше?
В тулките как я понял тоже, и там и там альфа или бэта. Причем текущую реализацию начали делать позже тебя и ее
уже сейчас можно начинать пробовать (хотя я смотрел твою реализацию, она приличнее в плане архитектуры).
IT>
var query = session.CreateCriteria<Simplest>().Add(Expression.Eq("Id",(long)id));
IT>Это конечно сильно? Офигенно читабельно и главное почти так же типобезопасно как и plain SQL. Уж лучше SQL:
Ну это не HQL Это CriteriaAPI, его кто-то уже экспрешенами кстати облагородил. В стиле
HQL это почти полный аналог SQL, с упрощеным синтаксисом джойнов. Т.е. запрос пишется также
как на сиквеле, но лаконичнее.
session.CreateQuery("from Simplest where id=:id").SetParameter("id", id)
Это лучше чем SQL, но сильно хуже линка.
Если использовать модель гибернейта не для тупого доступа как к графу объектов, а для построения
простых и читаемых запросов, она пока выглядит лучше тулкитовской т.к. коллекции всетаки дают больше преимуществ.
Как можно убрать маппинг коллекций и оставить такую же понятную запись?
from u in Users
where u.Departments.Any(d => d.Type == type)
select u.Operations.Sum(o => o.Amount);
На HQL кстати будет такая же по понятности, но без контроля компилятора.
Да, у хибера серьезные проблемы с производительностью, но как инструмент по борбе со сложностью модели он пока не имеет равных.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[35]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, IT, Вы писали:
C>>Для анализа в случае проблем. IT>Тебе так важно нажал пользователь кнопку или повозил по экрану мышкой? А скриншотик ты на всякий случай не сохраняешь? И запись с вебкамеры за последние 10 минут работы пользователя тоже очень могут помочь.
Скриншоты сохраняются в случае необработанного исключения и автоматически добавляются к баге в Jira.
Действия в аудите обычно сложнее, чем "нажал кнопку". К примеру: "добавил роль XXX в организации YYY к пользователю ZZZ, вступающую в действие начиная с aa.bb.20cc dd:ee".
C>>>>Придётся. Во-первых, в EditableObject нет вычисления изменений (добавить несложно, согласен). IT>>>IsDirtyMember устроит? C>>Даже близко не устроит. IT>Тогда что ты подразумеваешь под вычислением изменений?
В смысле, что это такая микроскопическая часть, что о ней говорить смешно.
C>>Вот теперь то же самое для всех коллекций, с правильными каскадами. Как только оно всё заработает — ты уже почти полностью напишешь классическую ORM. IT>Ты о чём? Ты просил треккинг, получи. Если ты хочешь получать уведомления, подписывайся и получай.
Объясняю ещё раз. Мне нужен трекинг ВСЕХ изменений. Без необходимости делать кучу шаманств. Так вот, если его сделать — ты получишь классическую ORM.
C>>Нет, это просто вы неправильно там в IBM всё делали. Засасывающего тут только простота использования — создаёшь объект, добавляешь куда надо, и забываешь про него. Оно всё там дальше само сделает. IT>Ну да. Оно там всё само делает только в примитивных, заранее определённых сценариях и в демках. А чтобы сделать простой аудит нужно попрыгать вприсядку вокруг костра с бубном.
Угу, а у тебя написать на ассемб^W Булките пару сотенок килобайт.
C>>Блин, в третий раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. IT>А при чём тут тогда NH?
А что ты думаешь на сервере работает?
C>>Я не вижу в чём "выразительность" BLToolkit'а. В том, что он всегда заставляет работать с SQL (кроме примитивных взятий объекта по ID)? IT>Как я понял, про Linq в NH пока лучше помолчать. Если так, то чем HQL лучше?
В Hibernate есть killer feature (правда, при неправильном использовании и для производительности) — навигационный доступ. Который позволяет свести к минимуму число явных запросов вообще.
Sapienti sat!
Re[35]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
C>>Блин, в третий раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>Причем тут связь с БД? Трекать изменения данных можно (и нужно) без БД. G>ADO.NET Data Services вполне умеет трекать изменения на клиенте при этом поддерживается маппинг и Linq.
Изменения не на клиенте происходят.
Sapienti sat!
Re[36]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
C>>>Блин, в третий раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>>Причем тут связь с БД? Трекать изменения данных можно (и нужно) без БД. G>>ADO.NET Data Services вполне умеет трекать изменения на клиенте при этом поддерживается маппинг и Linq. C>Изменения не на клиенте происходят.
Ну тогда еще проще: батч запросов + last modified. И в принципе становится пофиг какой ORM.
Re[37]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
C>>>>Блин, в третий раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>>>Причем тут связь с БД? Трекать изменения данных можно (и нужно) без БД. G>>>ADO.NET Data Services вполне умеет трекать изменения на клиенте при этом поддерживается маппинг и Linq. C>>Изменения не на клиенте происходят. G>Ну тогда еще проще: батч запросов + last modified. И в принципе становится пофиг какой ORM.
Блин, в четвёртый раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять.
Sapienti sat!
Re[38]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
C>>>>>Блин, в третий раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>>>>Причем тут связь с БД? Трекать изменения данных можно (и нужно) без БД. G>>>>ADO.NET Data Services вполне умеет трекать изменения на клиенте при этом поддерживается маппинг и Linq. C>>>Изменения не на клиенте происходят. G>>Ну тогда еще проще: батч запросов + last modified. И в принципе становится пофиг какой ORM. C>Блин, в четвёртый раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять.
При чем тут связь с БД?
Клиент регулярно дергает сервер с запросом: дай мне список изменений с даты last_modified с таким-то предикатом.
Вернее с батч таких запросов по всем коллекциям.
Re[39]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
C>>Блин, в четвёртый раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>При чем тут связь с БД? G>Клиент регулярно дергает сервер с запросом: дай мне список изменений с даты last_modified с таким-то предикатом. G>Вернее с батч таких запросов по всем коллекциям.
Несерьёзно. См. что я там написал.
Это придётся клиентам по всем таблицам всё время запросы делать. С пост-обработкой результатов с учётом ACL.
В общем, не жилец этот вариант.
Sapienti sat!
Re[40]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
C>>>Блин, в четвёртый раз уже говорю, что клиент вообще не держит связи с БД. Более того, он и не может его держать — иначе ему на каждый чих придётся мегабайты данных гонять. G>>При чем тут связь с БД? G>>Клиент регулярно дергает сервер с запросом: дай мне список изменений с даты last_modified с таким-то предикатом. G>>Вернее с батч таких запросов по всем коллекциям. C>Несерьёзно. См. что я там написал.
Помоему вполне нормально.
C>Это придётся клиентам по всем таблицам всё время запросы делать.
Ну если батчить запросы, то все ОК. Теб более что большинство из них не будет ничего возвращать.
C>С пост-обработкой результатов с учётом ACL.
С пост-обработкой — действительно несерьезно, а вот с навешиванием дополнительного предиката, в зависимости от ACL — вполне нормально.
C>В общем, не жилец этот вариант.
Очень даже жилец. И как раз с BLToolkit такой вариант проще всего сделать.
Хотя мне не нравится сама идея держать на клиенте мегабайт данных и их обновлять их постоянно.
Re[41]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
C>>Это придётся клиентам по всем таблицам всё время запросы делать. G>Ну если батчить запросы, то все ОК. Теб более что большинство из них не будет ничего возвращать.
См. ниже.
C>>С пост-обработкой результатов с учётом ACL. G>С пост-обработкой — действительно несерьезно, а вот с навешиванием дополнительного предиката, в зависимости от ACL — вполне нормально.
Уже третий раз говорю, что оно невозможно. Или потребует таких извращений на уровне БД, что Hibernate будет цветочками.
C>>В общем, не жилец этот вариант. G>Очень даже жилец. И как раз с BLToolkit такой вариант проще всего сделать.
Сейчас у меня 800 сущностей. Ты хочешь, чтобы по восьмистам таблицам тысяча клиентов одновременно постоянно выполняла запросы?
Причём вполне реально, у меня тысяча клиентов в моей схеме не полностью нагружают лишь два процессора 8-ядерного сервера.
Сколько серверов в твоём случае потребуется? Скажи, ты продаёшь суперкомпьютеры?
G>Хотя мне не нравится сама идея держать на клиенте мегабайт данных и их обновлять их постоянно.
Их там около 30 мегабайт.
Sapienti sat!
Re[42]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
C>>>Это придётся клиентам по всем таблицам всё время запросы делать. G>>Ну если батчить запросы, то все ОК. Теб более что большинство из них не будет ничего возвращать. C>См. ниже.
C>>>С пост-обработкой результатов с учётом ACL. G>>С пост-обработкой — действительно несерьезно, а вот с навешиванием дополнительного предиката, в зависимости от ACL — вполне нормально. C>Уже третий раз говорю, что оно невозможно. Или потребует таких извращений на уровне БД, что Hibernate будет цветочками.
Ну покажи чтоли что у тебя там за система такая с ACL.
C>>>В общем, не жилец этот вариант. G>>Очень даже жилец. И как раз с BLToolkit такой вариант проще всего сделать. C>Сейчас у меня 800 сущностей. Ты хочешь, чтобы по восьмистам таблицам тысяча клиентов одновременно постоянно выполняла запросы?
А сейчас как клиенты узнают об изменениях?
Ты же говорил что у тебя веб. Значит делают запросы.
C>Причём вполне реально, у меня тысяча клиентов в моей схеме не полностью нагружают лишь два процессора 8-ядерного сервера.
Поздравляю.
C>Сколько серверов в твоём случае потребуется?
Думаю что один + сервер БД.
C>Скажи, ты продаёшь суперкомпьютеры?
Нет.
G>>Хотя мне не нравится сама идея держать на клиенте мегабайт данных и их обновлять их постоянно. C>Их там около 30 мегабайт.
"Там" это где? Ты передаешь по 30 мб данных на клиентов? А что они с ними делают?
Человеку никак нереально просмотреть такой объем в разумные сроки.
Re[32]: Фреймфорк для разработки Веб и десктоп-приложений на
От:
Аноним
Дата:
01.10.09 10:58
Оценка:
Здравствуйте, gandjustas, Вы писали:
G> Даже препоганейший lazy load довольно неплохо работает на enmedded DB в десктопных сценариях.
А можно просветить почему lazy load "препоганейший"??
Re[33]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
G>> Даже препоганейший lazy load довольно неплохо работает на enmedded DB в десктопных сценариях. А>А можно просветить почему lazy load "препоганейший"??
Простой пример. Есть пользователи и группы, связаны один-ко-многим. Связанные группы подгружаются с помощью LL.
foreach(var user in users)
{
Console.WriteLine(user.Name);
foreach(var group in user.Groups)
{
Console.WriteLine(" " + group.Name);
}
}
Посчитай сколько запросов к базе будет.
Хотя достаточно одного джоина.
При этом аналогичная проблема с LL встречается не то что часто, а повсеместно, особено если код декомпозирован.
Например "невинное" обращение к связанной коллекции при генерации view в вебе может вылится в допонительную сотню запросов и страшные тормоза.
В случае embedded DB LL оправдан, так как чаще всего эти операции приводят к обращениям к памяти самого процесса, поэтому нет затрат на пересечение границ процессов и количество вызовов роли почти не играет.
Re[43]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
C>>Уже третий раз говорю, что оно невозможно. Или потребует таких извращений на уровне БД, что Hibernate будет цветочками. G>Ну покажи чтоли что у тебя там за система такая с ACL.
Есть организации, и пользователь может работать в нескольких организациях. Организации объединены в иерархии, внутри каждой организации ещё и набор иерархических ролей.
Объекты могут принадлежать одновременно нескольким иерархиям, причём их набор может меняться во время жизни объекта.
G>>>Очень даже жилец. И как раз с BLToolkit такой вариант проще всего сделать. C>>Сейчас у меня 800 сущностей. Ты хочешь, чтобы по восьмистам таблицам тысяча клиентов одновременно постоянно выполняла запросы? G>А сейчас как клиенты узнают об изменениях?
Им они присылаются сервером.
G>Ты же говорил что у тебя веб. Значит делают запросы.
Где я говорил про веб? У меня "толстый клиент" на основе WebStart.
C>>Сколько серверов в твоём случае потребуется? G>Думаю что один + сервер БД.
Не хватит. 800*1000 = 800000 запросов где-то в 5 секунд. Что-то многовато. Даже если оптимизировать (не запрашивать каждый раз всё), то всё равно нагрузка будет очень нехилая.
G>>>Хотя мне не нравится сама идея держать на клиенте мегабайт данных и их обновлять их постоянно. C>>Их там около 30 мегабайт. G>"Там" это где? Ты передаешь по 30 мб данных на клиентов? А что они с ними делают?
Смотрят.
G>Человеку никак нереально просмотреть такой объем в разумные сроки.
Речь идёт не о табличных данных. Например, нужна способность смотреть данные по расписанию для определённого департамента для планирования события, причём для планирования нужно учитывать, чтоб не было overtime'а. Это выглядит для пользователя очень безобидно, но внутри требует перелопатить кучу данных.
Можно было бы вынести на сервер кое-что, но тогда многие операции выполнялись бы не мгновенно, а с многосекундной задержкой (на передачу результатов).
Sapienti sat!
Re[34]: Фреймфорк для разработки Веб и десктоп-приложений на
От:
Аноним
Дата:
01.10.09 11:46
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>Посчитай сколько запросов к базе будет. G>Хотя достаточно одного джоина.
G>При этом аналогичная проблема с LL встречается не то что часто, а повсеместно, особено если код декомпозирован. G>Например "невинное" обращение к связанной коллекции при генерации view в вебе может вылится в допонительную сотню запросов и страшные тормоза.
Идею понял.
Мне кажется, что описанная проблема это ошибки дизайна, а не LL. Тоесть, вышеописанную ситуацию можно обернуть в какой нить класс, который при первом обращении к коллекции груп делают тот же самый запрос с джоином.
Это просто мысли. Я могу и ошибаться.
Re[34]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, gandjustas, Вы писали:
А>>А можно просветить почему lazy load "препоганейший"?? G>Простой пример. Есть пользователи и группы, связаны один-ко-многим. Связанные группы подгружаются с помощью LL.
G>
G>foreach(var user in users)
G>{
G> Console.WriteLine(user.Name);
G> foreach(var group in user.Groups)
G> {
G> Console.WriteLine(" " + group.Name);
G> }
G>}
G>
G>Посчитай сколько запросов к базе будет. G>Хотя достаточно одного джоина.
Просто справедливости ради замечу, что проблема здесь вовсе не в самом LL, а в том как он используется.
При желании можно заставить тот же Hiberante загрузить пользователя с его группами как раз за один селект c джойном, хотя есть и другие достаточно эффективные способы загрузки коллекций.
Вот например (Join fetching): http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching
Re[44]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, gandjustas, Вы писали:
C>>>Уже третий раз говорю, что оно невозможно. Или потребует таких извращений на уровне БД, что Hibernate будет цветочками. G>>Ну покажи чтоли что у тебя там за система такая с ACL. C>Есть организации, и пользователь может работать в нескольких организациях. Организации объединены в иерархии, внутри каждой организации ещё и набор иерархических ролей.
Ну так а сами ACL как выглядят?
C>Объекты могут принадлежать одновременно нескольким иерархиям, причём их набор может меняться во время жизни объекта.
G>>>>Очень даже жилец. И как раз с BLToolkit такой вариант проще всего сделать. C>>>Сейчас у меня 800 сущностей. Ты хочешь, чтобы по восьмистам таблицам тысяча клиентов одновременно постоянно выполняла запросы? G>>А сейчас как клиенты узнают об изменениях? C>Им они присылаются сервером.
G>>Ты же говорил что у тебя веб. Значит делают запросы. C>Где я говорил про веб? У меня "толстый клиент" на основе WebStart.
Ну если так — тогда еще проще. Все изменения которые происходят прогоняются через механизм разрешений, и отправляются клиентам в них нуждающимся.
Это вообще ортогонально доступу к данным получается. И через АОР прикручивается.
C>>>Сколько серверов в твоём случае потребуется? G>>Думаю что один + сервер БД. C>Не хватит. 800*1000 = 800000 запросов где-то в 5 секунд. Что-то многовато. Даже если оптимизировать (не запрашивать каждый раз всё), то всё равно нагрузка будет очень нехилая.
ну с чего ты взял что 800 запросов будет. Будет один батч от одного клиента, всего максимум 200 запросов в секунду, большая часть запросов даже до БД не дойдет так как метки последнего изменения будут закешированы на сервере.
G>>>>Хотя мне не нравится сама идея держать на клиенте мегабайт данных и их обновлять их постоянно. C>>>Их там около 30 мегабайт. G>>"Там" это где? Ты передаешь по 30 мб данных на клиентов? А что они с ними делают? C>Смотрят.
И что это за данные? Даже если картинки — это очень много.
Что показывается пользователю в итоге?
G>>Человеку никак нереально просмотреть такой объем в разумные сроки. C>Речь идёт не о табличных данных. Например, нужна способность смотреть данные по расписанию для определённого департамента для планирования события, причём для планирования нужно учитывать, чтоб не было overtime'а. Это выглядит для пользователя очень безобидно, но внутри требует перелопатить кучу данных.
Ну так и пусть данные лопаятся средствами сервера, бд, OLAP системы, а пользователю отдается конечный результат.
C>Можно было бы вынести на сервер кое-что, но тогда многие операции выполнялись бы не мгновенно, а с многосекундной задержкой (на передачу результатов).
Какие задержки на передачу результатов? Передать картинку размером с экран (около 200 кб) через интернет — дело десяти секунд. А реально данных для отображения будет на порядок меньше.
Re[35]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
G>>Посчитай сколько запросов к базе будет. G>>Хотя достаточно одного джоина.
G>>При этом аналогичная проблема с LL встречается не то что часто, а повсеместно, особено если код декомпозирован. G>>Например "невинное" обращение к связанной коллекции при генерации view в вебе может вылится в допонительную сотню запросов и страшные тормоза.
А>Идею понял. А>Мне кажется, что описанная проблема это ошибки дизайна, а не LL.
LL и есть ошибка дизайна в большинстве случаев.
Явная загрузка данных из БД всегда рулит, но она нарушет "красоту" ООП.
А>Тоесть, вышеописанную ситуацию можно обернуть в какой нить класс, который при первом обращении к коллекции груп делают тот же самый запрос с джоином. А>Это просто мысли. Я могу и ошибаться.
Естественно ты ошибаешься, так как если бы это было действительно просто, то уже давно бы сделали.
Re[35]: Фреймфорк для разработки Веб и десктоп-приложений на
Здравствуйте, Овощ, Вы писали:
О>Здравствуйте, gandjustas, Вы писали:
А>>>А можно просветить почему lazy load "препоганейший"?? G>>Простой пример. Есть пользователи и группы, связаны один-ко-многим. Связанные группы подгружаются с помощью LL.
G>>
G>>foreach(var user in users)
G>>{
G>> Console.WriteLine(user.Name);
G>> foreach(var group in user.Groups)
G>> {
G>> Console.WriteLine(" " + group.Name);
G>> }
G>>}
G>>
G>>Посчитай сколько запросов к базе будет. G>>Хотя достаточно одного джоина.
О>Просто справедливости ради замечу, что проблема здесь вовсе не в самом LL, а в том как он используется.
Грубо говоря проблема чаще всего в том, что используется LL.
очень мало ты сможешь найти примеров где LL оправдан хоть немного.
О>При желании можно заставить тот же Hiberante загрузить пользователя с его группами как раз за один селект c джойном, хотя есть и другие достаточно эффективные способы загрузки коллекций. О>Вот например (Join fetching): http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching
Если есть проблема SELECT N+1 — как описана в примере — то лечится она только загрузкой сущности со связанными.
А современные фреймворки позволяют вообще написаnь так:
var q = from u in users
select new {u.Name, Groups = u.Groups.Select(g => new {g.Name})};
foreach(var user in q)
{
Console.WriteLine(user.Name);
foreach(var group in user.Groups)
{
Console.WriteLine(" " + group.Name);
}
}
И получит только необходимые данные ровно одним запросом.
Re[36]: Фреймфорк для разработки Веб и десктоп-приложений на
G>var q = from u in users
G> select new {u.Name, Groups = u.Groups.Select(g => new {g.Name})};
G>
G>И получит только необходимые данные ровно одним запросом.
EF точно так умеет? Это некислая оптимизация, дровишки проверенные?
Кстати, маппинг коллекций вроде как был считался признаком H/ORM, или без LL не считается?
Так без LL можно и хибер настроить.
Пример про страшный ЛЛ хорош, но помнишь, как ты рассказывал, что используешь трекинговые свойства в EF
только для джойнов в запросах, а в остальном у тебя абсолютно анемичная модель? Так вот коллекции в хибере
можно использовать точно так же.
Страшные сказки, что глупые программисты сразу понапишут кучу вложенных циклов по коллекциям можно уже не
повторять, такие программисты и на линке повтыкают ToList() и те же грабли ударят не хуже.
foreach(var user in db.Users.Select(u => new { u.Id, u.Name }))
{
Console.WriteLine(user.Name);
foreach(var ug in db.UserToGroup().Where(ug => ug.UserId == user.Id)).Select(ug => ug.GroupId))
{
var group = db.Groups.Where(g => g.Id == ug.GroupId).Single();
Console.WriteLine(" " + group.Name);
}
}
Как видишь, до маразма можно довести любую технологию, я взял сугубо анемичную модель без
навигационных свойств, выбирал каждым запросом "только необходимый минимум данных".
Итог? Программист мыслящий объектами и циклами в хибере наломает меньше дров,
а мыслящий реляционными понятиями и в хибере выберет все что нужно одним запросом.