LINUX.ORG.RU

Архитектура javaee-приложения

 ,


0

3

Имеется javaee-приложение. В качестве БД используется монго. Для доступа к монго есть singleton-бин. В приложении нужно оперировать некими сущности. Допустим, есть сущности User и Bid (заявка). Все типы сущностей имеют схему (хранится в БД) и ещё некоторые общие поля. Конкретные типы имеют также свои уникальные поля. В самой программе эти сущности не представлены в виде DTO или чего-то подобного, т.е. не имеют отображения на конкретный класс (ввиду непостоянства их полей) информация хранится в обычных экземплярах org.bson.Document (Это новый класс, появился в 3-й версии драйвера для явы. На деле он имплементит Map<String, Object> и ещё что-то. Короче, с точки зрения доступа к инфе можно считать, что это обычная Map).

Как правильнее, с точки зрения концепции javaee организовать архитектуру?

Нужно создать некую абстракцию для этих сущностей, чтобы можно было удобно работать с ними. Хочется, чтобы это выглядело так:

public void editUser(Document doc) {
    user.init(doc);
    user.save();
}
По-идее, надо сделать 2 интерфейса (User, Bid) и их реализацию в виде бинов (UserBean, BidBean). Например:
public interface AbstractDoc {
    public Document getSchema();
    public void updateSchema(Document schema);
    public void init(Document data);
    public <T> T getField(String name, Class<T> fieldType);
}
public interface User {
    public void register();
    public List<Bid> getBids();
}
public interface Bid {
    public User getUser();
}
Вот тут и встаёт вопрос. У юзера и у заявки есть поля со взаимными отношениями. По идее, реализация этих интерфейсов - Stateless бины, чтобы иметь возможность инжектить (тот же монго-сервис, чтобы сохранять в БД) и инжектиться самим (в JAX-RS ресурс, к примеру). С другой стороны, заявка не бывает без пользователя, и можно её сделать обычным классом, а все действия производить через User-бин. Но как тогда, к примеру, получить список всех заявок или пользователей? Статические методы не приемлемы в интерфейсах. Заводить вспомогательный класс-бин, инжектить его в User и сделать геттер на него? Или всё реализовать это как репозиторий, по типу EntityManager? Тогда как отслеживать связи? Брать ОРМ типа Morphia тоже не хочется как-то. Как вообще принято в javaee делать такое?


В качестве БД используется монго...
...есть сущности User и Bid (заявка)...
У юзера и у заявки есть поля со взаимными отношениями...

ССБЗ. Вопрос не касается архитектуры.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

А где ещё хранить такое? Админ через админку может добавить/изменить/удалить поле в схеме юзера, т.е. структура будет изменчивой. Сами заявки могут храниться в поле у юзера, или же быть в отдельной таблице, это не важно. Важно то, как их лучше представить в самом коде, чтобы не работать напрямую с Document.

memnek
() автор топика
Ответ на: комментарий от memnek

А где ещё хранить такое?

Какое такое? Ссылки между сущностями? В RDBMS конечно же.

Сами заявки могут храниться в поле у юзера, или же быть в отдельной таблице, это не важно

Важно. Втыкаешь юзеру поле «список заявок» и твои проблемы решены.

ya-betmen ★★★★★
()
Ответ на: комментарий от memnek

Админ через админку может добавить/изменить/удалить поле в схеме юзера, т.е. структура будет изменчивой

По слухам в PostgreSQL завезли json-поля, а xml-поля, опять же по неподтвержденным слухам, там были уже достаточно долго.

Архитектурная проблема действительно есть, но она находится на ступеньку выше - monga.

trex6 ★★★★★
()
Ответ на: комментарий от trex6

Архитектурная проблема действительно есть, но она находится на ступеньку выше - monga.

Да проблема не в монге, а в том, что в ТС пытается пихать связанные данные в БД, которая в них не умеет. Вполне вероятно он данные и так данные туда впихнуть может, только надо схему хранения пересмотреть.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Какое такое?

Schemaless данные. Схема как бы есть, но она изменчивая и больше нужна для генерации/валидации полей на клиенте.

Втыкаешь юзеру поле

Это можно, но есть несколько проблем: документ юзера может быть довольно большим (в монге ограничение на размер 1 доумента, при индексации вроде как потребуется больше оперативы, да и при выгрузке в java-приложение будет большое потребление памяти), плюс локи монги (сейчас вроде только на документ, но на самом деле всё зависит от реализации).

Ладно, я сообразил уже, как лучше сделать, спасибо за наводки!

memnek
() автор топика
Ответ на: комментарий от ya-betmen

которая в них не умеет

Умеет, но просто join'ить данные надо вручную, а не силами БД. В принципе, ORM типа морфии такое сами могут. Транзакции тоже можно устроить, даже силой самой монги.

memnek
() автор топика
Ответ на: комментарий от memnek

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

rusich
()
Ответ на: комментарий от ya-betmen

Кстати говоря. Обычно совершенно не до курения монги, но всегда интересовал данный вопрос. Как у них в этих schemaless имплементируются/сублимируются связи и где можно посмотреть инфы на этот счет? Пару раз бегло гуглил, но без нужды особо не вникал. Если есть множество связей один ко многим между сущностями (ну ок, пусть даже 3 сущности, между которыми есть связи один ко многим), то как это принято хранить в монгах и прочих кассандрах? Как только начинаю над этим думать, через минуту прихожу к выводу, что один из вариантов - выделить корневой документ (единственный тип документа в небольшой системе), в полях которого будут храниться все связанные сущности. От такой мысли становится страшно.

А как вспоминаешь, что там ещё и транзакций из коробки нет, так прям совсем же жуть.

bytecode ★★
()
Последнее исправление: bytecode (всего исправлений: 1)
Ответ на: комментарий от bytecode

Если коротко то никак. Если длинно, то надо пересмотреть структуру данных чтоб у тебя были только объекты верхнего уровня и всё остальное лежало у них внутри.

Все эти kv хранилища придумали как раз для случаев когда связей нет и реляционные бд избыточны. Просто многу так раскрутили что появилось ощущение что ей всегда можно заменить мускуль.

ya-betmen ★★★★★
()
Ответ на: комментарий от memnek

Умеет, но просто join'ить данные надо вручную, а не силами БД

И целостность данных проверять тоже вручную, а не силами БД. В результате вся логика БД перекочует в приложение, ну и спрашивается для чего нужен носкуль внизу (при таком подходе данные хоть в файлах можно хранить) если поверх него скульный функционал выполняет приложение?

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

именно, монга просто поднапряглась и сделала простую и удобную систему сертификации/обучения

rusich
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.