Поля-списки в объектных БД
Интересный момент с сохранением свойств-списков в объектных БД.
Если мы рассмотрим ORM как образец - то как мы привыкли там - в ActiveRecord или в Hibernate, мы должны неким образом (через схему или маппинг) описать какие свойства сохранять, то их ORM будет сохранять - в том числе и списки. Т.е. хотя описываем мы списки неким специальным образом ( или или has_many каким), но по сути просто как еще одно свойство:
И с этого момента ORM начинает управлять коллекцией - если я что в нее добавлю, удалю или еще что-то, то изменения сохранятся в БД (в случае hibernate конечно есть еще вариант с invert, но разговор не о том).
А с объектными БД, в моем случае - Db4o, описания по умолчанию не требуется - ты просто сохраняешь объект в БД и потом получаешь его обратно (код в упрощенно-сыром виде, для наглядности):
Т.е. выше был весь код чтобы сохранить объект - ничего более не требуется. Но вот на днях обнаружил проблему что если к выбранному в примере объекту-статье попробуем добавить комментарии - то все станет работать не совсем так как представлялось по опыту с ORM. Для моей проблему это выглядело так что первый "комментарий" к статье сохранялся - но всегда оставался один, больше одного почему-то не сохранялось.
Т.е. вот этот тест заканчивается ошибкой - вместо двух комментариев у статьи сохраняется только один:
Оказывается что причина в том что Db4o рассматривает списки, так же как и остальные ссылочные объекты. Т.е. если у меня есть объект, в нем есть какие-либо поля, то механизм БД сохраняет изменения этих полей, но если мы там держим ссылку на некоторый объект то механизм сохранит ссылку и объект на который указывает данная ссылка, только в случае изменения. А если изменения были внутри объекта на который указывает ссылку то механизм естетсвенно не сохраняет их, поскольку если бы он всегда анализировал и сохранял изменения для всех полей, то граф объектов для которых надо сохранить изменения мог получаться очень большим. Собственно так же работают и ORM - если нужно чтобы сохранились изменения и в объекте на который мы сохраняем ссылку то требуется это указать с помощью cascade, но это не касается коллекций. А поскольку Db4o рассматривает список просто как еще один объект на который есть ссылка, а когда я добавляют новый элемент - то я изменяю именно список а не тот объект который сохраняю - то и измнения в список не сохраняются.
Ну а решение проблемы - это то что в Db4o есть возможность каскадные обновления включить и вот нам надо сделать конфиг и в нем описать что для нашего поля со списочным типом надо включить каскадное обновление.
Ну на мой вкус, логичнее было бы чтобы механизм БД был бы aware of списков (т.е. по умолчанию обновления в списках сохранял, а не рассматривал их как еще один ссылочный тип), поскольку как еще с ними работать кроме как с поддержкой обновлений. Надо будет на досуге посмотреть как ведут себя другие объектные бд (neodatis или ravendb например) при сохранении полей-списков.















