![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
Ортхэннер |
|
||||||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Имеем следующий класс:
Можно ли одним запросом "выдернуть" всех потомков исходного объекта вне зависимости от поколения? (т. е. чтобы не только
но и
и т. д.) |
||||||
|
|||||||
Plamenk |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 258 Регистрация: 18.2.2003 Репутация: нет Всего: 3 |
Средствами Oracle можно. См. "connect by prior".
Но судя по коду ты работаешь с объектами не БД... так что этот способ здесь наверное не поможет. |
|||
|
||||
powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 28 Всего: 159 |
Если ты вытянешь корневой объект (т.е. предка для тех потомков которые ищешь), то связанные объекты будут загружены либо автоматом (для односсылочных связей), либо лениво. Фактически делать ничего не нужно, только грамотно ссылки перебрать.
|
|||
|
||||
Ортхэннер |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Да знаю я, что они лениво будут загружены! Только дело-то в том как раз, что мне не надо, чтобы они грузились! Иначе приложение память будет кушать только в путь, да и медленнее обходить дерево таким образом, нежели на автомате. Ну ты сам посуди - это ж надо всё дерево будет в память загрузить. Куда это годится?
2 Plamenk: это и правда не оракул. Это Java Persistence. То есть БД там есть, но спрятана достаточно глубоко, и добраться до неё... можно, но, опять же, где гарантия, что это будет Oracle? у меня на машине вообще Java DB стоит... а надо, чтобы и с мусклом работало, и с Postgres... так что SQL-запросы если и можно использовать, то очень осторожно. |
|||
|
||||
tux |
|
||||
![]() Летатель ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1853 Регистрация: 10.2.2005 Где: msk.ru Репутация: 74 Всего: 132 |
Мне кажется или у вас что-то здесь не сходится? Если надо загрузить всех потомков, тогда будет кушать, если не надо, тогда не будет. По-моему, все просто. Не вижу проблем в обходе дерева, причем тут скорость не понятно. Плоский массив и дерево память будут расходовать одинаково - объекты одни и те же. Причем тут проблемы с памятью не ясно. Если нужно загрузить сразу все, просто поставь lazy=false. |
||||
|
|||||
Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 10 Всего: 40 |
Уважаемые, если выйти из тени JPA, то вот статья для размышления Дерево каталогов Nested Sets
|
|||
|
||||
powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 28 Всего: 159 |
В JPA это будет как fetch=FetchType.EAGER в аннотации типа связи. |
|||
|
||||
Ортхэннер |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Сорри, неправильно выразился. Надо получить количество потомков объекта. Но всех, а не только непосредственных. А скорость здесь при том, что обход дерева - задача более трудоёмкая, нежели перебор массива. К тому же рекурсия сама по себе склонна потреблять больше памяти, чем итерационные алгоритмы, - за счёт стека. |
|||
|
||||
Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 10 Всего: 40 |
||||
|
||||
Ортхэннер |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Уважаемый пугает своей наивностью. Всему своё место, знаете ли. Мне просто реально памяти не хватит - всё дерево обойти в нескольких потоках одновременно. StackOverflowError - видели такое?
|
|||
|
||||
Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 10 Всего: 40 |
Какой же такой гигантской глубины у вас дерево, если стека не хватает?
|
|||
|
||||
Ортхэннер |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Да не в глубине дело, вернее, не только в ней... кстати она не фиксирована, в общем случае - от 4 и выше. Там на последних двух уровнях у каждого узла уйма потомков получается. :-\ А поскольку крутится всё это не само по себе, а в компании много чего ещё - доступный объём памяти оказывается весьма ограничен. Плюс каждый поток работает с базой самостоятельно (пул, конечно, есть, но от этого не легче - это ж пул соединений с БД, а когда данные уже извлечены...), то есть при подключении десяти клиентов в памяти окажется десять "деревьев". И тут реально одно из двух - или OutOfMemoryError, или StackOverflowError, смотря по тому, хватит памяти на загрузку последней копии базы или нет. В любом случае дёргать объекты получается некошерно. Можно, конечно, делать выборку чисто ID... в этом случае памяти хватит. Но, откровенно говоря, хотелось бы всё-таки переложить эту работу на сервер приложений, а не трахаться самому... вот и интересуюсь - есть способ?
|
|||
|
||||
Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 10 Всего: 40 |
ну-ну, от такой рекурсии просто почти стопроцентное попадание на переполнение стека. Добавлено через 7 минут и 50 секунд всё, больше в занозу не лезу. ![]() |
|||
|
||||
Ортхэннер |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 29.1.2005 Где: Благовещенск Репутация: нет Всего: нет |
Платон, хочешь верь, хочешь нет, но такая ситуация реально была. Ты знаешь, сколько объектов находится на одном уровне иерархии? или размер в памяти одного объекта? или объём доступной памяти? нет?
Тогда хватит иронизировать. Нечего посоветовать по сабжу, лучше и правда молчи. |
|||
|
||||
Hroft |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 20.10.2003 Где: Москва Репутация: нет Всего: 3 |
Мне кажется, Platon всего лишь хотел сказать, что у вас принципиально что-то неправильно продумано. Он хочет вам помочь, а не выслушивать "да я сам все знаю, все умею, и вы ни фига не представляете, что у меня тут за МЕГАЗАДАЧА". Нужно как-то уважительнее относиться друг к другу.
Да, ситуации бывают разные. Но за 7 лет программирования я не видел ни одного StackOverflowError, вызванного сложностью задачи. Зато видел предостаточно вызванных... ммм... некорректным кодом. Даже если рекурсия глубокая, кто заставляет хранить данные в автопеременных? Для больших объемов данных есть куча, может быть, полезно будет свой менеджер памяти небольшой сваять, хотя, опять же, в яве все это смотрится более чем подозрительно. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |