|
|
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
Доброго всем времени суток. Есть EJB3. Есть отношение @OneToMany Таблица А - одна запись Таблица B - много. Связь должна двунаправленная. В энтити для таблицы А пишу @OneToMany(mappedBy="field из ентити для В") private List<Permission> permissions = new ArrayList<Permission>(); В энтити для таблицы B пишу @ManyToOne(cascade=CascadeType.ALL) @JoinColumn(name="id_application") private Application application; Ведущей в этом отношении выстыпает таблица В. При удалении записи из А выполняется N+1 запрос для чистки B.\ Как мне сделать чтобы ведущей в отношении стала А ? и при удалении из А выполняля delete from B по ключу связи ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 11:33:01 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
Поставить каскад в @OneToMany ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 11:41:05 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
В энтити для таблицы А добавил @OneToMany(mappedBy="field из ентити для В", cascade=CascadeType.ALL) private List<Permission> permissions = new ArrayList<Permission>(); Результат тот же!. тут удея в том что в отношении главной таблица B. КАк сделать чтобы в отношении главной стала А ? это сделать просто, если отношение однонаправленное, в двунаправленном - не знаю как!. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 11:49:52 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
"In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used" Все дело в mappedBy ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 12:00:19 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
Нароод !!!!!! че то я ваще зашиваюсь!!!!!! :(( попробуя сначала!!!!! но немного подругому!. Есть отношение @OneToMany Таблица А - одна запись Таблица B - много. Связь должна ОДНОНАПРАВЛЕННАЯ В энтити для таблицы А пишу @OneToMany(cascade={CascadeType.ALL}) @JoinColumn(name="id_application", nullable=false, insertable=true) private List<Permission> permissions = new ArrayList<Permission>(); В энтити для таблицы B без ссылок и упоминаний на А. перед удалением ентити по А проихходит вычитавание всех идентификаторов для В по внешнему ключу а потом само удаление проиходит по идентификаторам из В. т.е. три записи связано - три оператора delete. и т.д. как бы ему намекнуть что удалять можна по внешнему ключу одним delete:) ??????? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 14:01:53 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
это тебе к разработчикам контейнера ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 14:04:35 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
OneToMany ... Связь должна ОДНОНАПРАВЛЕННАЯ ... перед удалением ентити по А проихходит вычитавание всех идентификаторов для В по внешнему ключу а потом само удаление проиходит по идентификаторам из В. т.е. три записи связано - три оператора delete. и т.д. как бы ему намекнуть что удалять можна по внешнему ключу одним delete:) ??????? Если у вас hibernate то вот ответ на ваш вопрос http://www.sql.ru/forum/actualthread.aspx?tid=280115#2534263 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 14:42:59 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
прочитал инфу по линку. проникся важностью момента :) даа действительно надобы внимательнее раляционную модель с маппингом вязать!!. но всё это хорошо! но в EJB3 нет анатации all-delete-orhan! есть только хорошо изветсные CascadeType.ALL и д.р. использовать чисто гибернетовские анатации не хотелось бы!!!. хотелось бы на чистом EJB3. так возможно ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 15:44:43 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
OneToManyпрочитал инфу по линку. использовать чисто гибернетовские анатации не хотелось бы!!!. хотелось бы на чистом EJB3. так возможно ? Можно - сделайте связь bidirectional ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 16:14:31 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
так она у меня и так бидиректионал. В энтити для таблицы А (там де одна запись) пишу @OneToMany(mappedBy="application", cascade=CascadeType.ALL) private List<Permission> permissions = new ArrayList<Permission>(); В энтити для таблицы B (много записей) пишу @ManyToOne @JoinColumn(name="id_application") private Application application; Удаляю так : Application a = manager.find(Application.class, application.getId()); manager.remove(a); в итоге последовательно удаляются записи из B по своим айдишникам. три записи - три делете!. черыте - четыре делете. funikovyuri - что вы имеете ввиду ? или я неправильно мапиг оформил ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 16:37:52 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
можно и так : Application a = manager.find(Application.class, application.getId()); manager.createQuery("delete from Permission where application=:application").setParameter("application", a).executeUpdate(); manager.remove(a); но хотелось бы обойтись каскадностью для чистоты эксперимента. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 16:41:08 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
Опция Cascade.ALL нужен для того чтобы эскалировать операции save/update/delete на объекты, дочерние по отношение к данному объекту. К проблеме лишних delete from .. она отношения не имеет. Как написано по ссылке - в РБД нету связи один-ко-многим, поэтому hibernate так себя ведет. В случае если хибернейт будет иметь связь многие-к-одному он будет посылать такой delete какой вам, судя по всему, нужен. Судя по коду который вы в последних сообщениях привели у вас все верно написано, только @ManyToOne аннотация должна быть у getter'а, а не у самого property (@OneToMany при этом не трогайте) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2006, 17:58:30 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
да какая разница, как я анатирую - проперть или геттер ? это вопрос вкуса и привычки. насколько я понял из спецификации ejb3 смотрит как анатирован айдишник - если он анатирован пропертью - всё остальное тоже должно быть пропертью, если через гетер - всё остальное - также. но всё же последовал вашему совету и перенес @ManyToOne в гетер - поведение не изменилось - всё также гонит кучу делете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 08:56:30 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
про четыре delete: я признаюзь ни разу не видел у хибера таких delete. Эти четыре запроса ваполняются в одном batch'e поэтому проблем никаких. Думаю этим можно не грузиться. Такое поведение обьясняется следующим: delete каскадится с masterа на detailы они помечаются в сессии как коцнутые. При flush'е сессии хибер в нужном порядке удаляет объекты по их PK. И если например вы удалили пару мастеров (и кучу детэйлов с ними), то при flushЕ он не будет собирать detailы в пачки для удаления по одному FK. СУБДу думаю тоже фиолетово. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 09:40:50 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
да какая разница, как я анатирую - проперть или геттер ? это вопрос вкуса и привычки. насколько я понял из спецификации ejb3 смотрит как анатирован айдишник - если он анатирован пропертью - всё остальное тоже должно быть пропертью, если через гетер - всё остальное - также. но всё же последовал вашему совету и перенес @ManyToOne в гетер - поведение не изменилось - всё также гонит кучу делете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 10:29:29 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
админ - прошу прощения за то что гоню посятнно дубликаты постов. запарился вкрай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 10:31:40 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
попробовал удалить сразу в батче два мастера - да действительно он спева подчищает за первым мастером потом его грохает потом подчищает за вторым и грохает его. в итоге - было 2 мастера у каждого по две дочерних записи. всего запросов : 1 оператор делете на каждый чаил (4 штуки всего) + 2 delete на мастерах. = 6 операторов. то,что он делает это в батче - это не повод успокаиваться. как я понял - батч это одно обращение к базе. т.е. по сути имеем аналог на pl/sql begin delete from child where id = .. delete from child where id = .. delete from master where id = .. delete from child where id = .. delete from child where id = .. delete from master where id = .. end; а если там тысяча или милион ? уууууужжж наверняка логических чтений будет намного больше еслибы удаление шло по fk. я правильно представляю происходящую картину ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 10:49:24 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
OneToMany я правильно представляю происходящую картину ? нет... удалять одним delete'ом записи по FK для одного родителя hibernate может... сейчас немного освобожусь - нарисую вам пример ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 10:53:03 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
OneToMany т.е. по сути имеем аналог на pl/sql Сранение с PL/SQL, думаю не совсем имеет смысл, т.к. он выполняется базой, а тут проблема в том что хибер работает в другом адр. пр-ве. и общаются они последовательными запросами. begin/end - это транзакция - думаю за рамками сабжа. Если бы батча не было: запрос№1 "коц первую", ждём подтверждения, следующий запрос, ждём .... Батч уходит одним запросом. Т.е.не надо ждать выполнения мелких запросов. а субду думаю пофиг. можете опровергнуть бенчмарком. тока коректным плиз!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 11:22:55 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
to expp -> по-моему вы выразили тоже самое мнение что и я. только другими словами. я утверждаю что в случае батча хибер собирает кучу операторов в кучу и отправляет их целым блоком за одно обращение к базе!. выйгрыш по скорости конечно есть по сравнению с обращением к базе за кажым делет, но это не ПРИНЦИПИАЛЬНО!. юзеру все равно придется ждать завершения батча!. экономим время тока за счет сокращения лишних обращений. Объем производимой работы тот же!. что именно вы хотите чтобы я опроверг? уточните плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 14:35:53 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
ну покажите на тесте что стирать по FK быстрее чем по PK. Думаю разница незначительная. А разница между batch/неbatch принципиальная поскольку существенна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 14:57:30 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
извольте Код: plaintext 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. 46. 47. 48. 49. 50. 51. 52. результат Вставляли : 4259 Построчно : 4587 Зараз : 3443 В итоге то что можно сделать одним оператором всегда быстрее чем несколькими. об этом еще Том Кайт писал в своём двухтомнике! естественно это всё применительно к ораклу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 17:03:26 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
я просил корректный тест. хотелось бы убедиться что эти результаты воспроизводятся. запустите это плиз 10 раз (в одинаковых условиях, как это сделать я не знаю!!!). потом в скрипте пом5еняйте два способа удаления местами. и опять 10 раз в тех же условиях, плиз. вот потом можно посмотреть на результаты и как то их интерпритировать (см. мат стат) дальше: если же разница между двумя этими способами составлят 1,5 раза, при кол-ве итераций на 4 порядка больше то я думаю это незначительный оверхэд (если это вобще не тормоза интерпритатора PLа на for'е). ещё дальше: если эти полтора раза для на 4ёх порядках для вас существенны, то может вам не нужен хибер? он не для mass updateов в конце: остаётся ждать пока Юрий не освободиться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 18:37:33 |
|
||
|
@OneToMany
|
|||
|---|---|---|---|
|
#18+
Странное дело - я был уверен что уже решал эту задачу... но сейчас это сделать не удалось... т.е. да bidirectional убирает лишние update'ы, но не лишние delete'ы. Так что пока увы :( Зато у меня есть 2 workaround'а 1й это удалять объекты таким кодом: Код: plaintext 1. 2. 3. 4. 5. если убрать этот код в DAO метод то на мой взгляд получается нормально 2й это использовать Hibernate annotations extension, а именно @OnDelete(action=OnDeleteAction.CASCADE) совместно с каскадным DRI в схеме БД ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2006, 19:06:27 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=34216737&tid=2147141]: |
0ms |
get settings: |
12ms |
get forum list: |
24ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
122ms |
get topic data: |
17ms |
get forum data: |
5ms |
get page messages: |
90ms |
get tp. blocked users: |
2ms |
| others: | 308ms |
| total: | 590ms |

| 0 / 0 |
