Как стать автором
Обновить

Комментарии 31

Создаются классы предметной области и на них ставятся аннотации @Table, @Entity и.т.д.
Затем эти классы регистрируются в файле persistence.xml.

Руками каждый класс? Или хотя бы можно ограничиться только пакетом?


Рекомендуется использовать аннотацию @NamePattern — аналог метода toString() для читабельного отображения сущностей в пользовательском интерфейсе.

А это есть в Lombok. В купе с прочим скрытием бойлерплейта.


Полезные маркер-интерфейсы, которые дают дополнительные возможности
Versioned, SoftDelete, Updatable, Creatable

Это всё умеет и Spring через аннотации, причём аннотации гибче интерфейсов — можно использовать удобные для тебя имена полей.


Скрипты для создания и обновления БД генерируются автоматически при помощи CUBA Studio.

Так умеет Hibernate, но я считаю что ручное написание скриптов даёт не только больше контроля, но и на порядок больше возможностей…
Возьмите Flyway/Liquibase — и в перёд. Хоть чистый SQL, хоть XML с валидацией, хоть DSL.


Концепция “представлений” в CUBA может показаться несколько непривычной, но она достаточно легко объясняется.
Представление — это декларативный способ объявления атрибутов, значения которых необходимо извлечь из хранилища данных.

И это умеет Spring Data JPA: Projections


Дополнительно нужно зарегистрировать сервисы в файле web-spring.xml в модуле Web.

А в Spring Boot xml-файлы уже давно не нужны.


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

Тут или логическая ошибка или вы не с тем боритесь.

Disclaimer — CUBA не противопоставляется Spring Boot. CUBA можно рассматривать как Spring+ещё библиотеки, которые делают вашу жизнь проще при разработке типовых проектов.

Создаются классы предметной области и на них ставятся аннотации Table, Entity и.т.д.
Затем эти классы регистрируются в файле persistence.xml.

Руками каждый класс? Или хотя бы можно ограничиться только пакетом?

XSD для persistence.xml не разрешает указывать пакет (http://oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/index.html#2.2). Можно указать JAR файл, классы по отдельности и включить опцию «exclude-unlisted-classes», но она не работает для JavaSE persistence unit и, в теории, может принести что-то лищнее. CUBA Studio это автоматом делает, IDEA тоже может автоматизировать эту работу. И сущности делаются не так часто, так что неудобство минимальное.
Рекомендуется использовать аннотацию @NamePattern — аналог метода toString() для читабельного отображения сущностей в пользовательском интерфейсе.

А это есть в Lombok. В купе с прочим скрытием бойлерплейта.

@NamePattern не замена toString(), это дополнение для CUBA. Технически — можно использовать Lombok, мы его сознательно не тащим в платформу, чтобы не было лишних зависимостей и IDE без плагинов не сходили с ума.
Полезные маркер-интерфейсы, которые дают дополнительные возможности
Versioned, SoftDelete, Updatable, Creatable

Это всё умеет и Spring через аннотации, причём аннотации гибче интерфейсов — можно использовать удобные для тебя имена полей.

  • Version ставится над полем, в 90% случаев, я думаю, это поле будет называться version и дальше про него все забудут. Зачем нужен бойлерплейт?
  • То же самое можно сказать про @CreatedDate и @LastModifiedDate.
  • Про поддержку soft delete я не нашел, есть только jira.spring.io/browse/DATAJPA-307 и рекомендации, как это можно сделать вручную.

Скрипты для создания и обновления БД генерируются автоматически при помощи CUBA Studio.

Так умеет Hibernate, но я считаю что ручное написание скриптов даёт не только больше контроля, но и на порядок больше возможностей…
Возьмите Flyway/Liquibase — и в перёд. Хоть чистый SQL, хоть XML с валидацией, хоть DSL.

Это хорошее и правильное замечание и тема для отдельного исследования. В CUBA так исторически сложилось, что делали генерацию SQL, в те времена Liquibase не очень подошла. У меня есть задача взвесить все «за» и «против» переезда на одну из этих библиотек. Кроме того, скрипты SQL, которые генерирует CUBA, делаются в виде файлов и можно посмотреть, что было сгенерировано и даже поправить руками или дописать свое, если требуется, перед тем, как применять изменения. Это не черный ящик. Скрипты SQL попадают в codebase, коммитятся в Git и они вообще часть проекта.
Концепция “представлений” в CUBA может показаться несколько непривычной, но она достаточно легко объясняется.
Представление — это декларативный способ объявления атрибутов, значения которых необходимо извлечь из хранилища данных.

И это умеет Spring Data JPA: Projections

Есть нюанс: данные тянутся из базы все, а потом преобразуются спрингом. А в случае View из базы не выбираются ненужные поля. Т.е., если в сущности 100 атрибутов, а тебе на форме нужен один, то из базы вытащится 100, а потом Projection сделает DTO с одним атрибутом.
Дополнительно нужно зарегистрировать сервисы в файле web-spring.xml в модуле Web.

А в Spring Boot xml-файлы уже давно не нужны.

Да, верно, но там нет раздельного деплоя services и controllers из коробки, надо руками дописывать. И есть шанс, что при разработке такого механизма может получиться так, что потребуется XML файл, в котором будут прописаны сервисы, для которых надо делать прокси. А может и не потребоваться. У нас так получилось пока.
Сейчас ведется борьба с уменьшением XML, переходим на аннотации там, где возможно.

Тут или логическая ошибка или вы не с тем боритесь.

Боремся с тем, чтобы XML файлов было как можно меньше :-)
CUBA Studio это автоматом делает, IDEA тоже может автоматизировать эту работу. И сущности делаются не так часто, так что неудобство минимальное.

Ну одно дело один раз указать пакет с сущностями и потом указать @Entity, и совсем другое каждый раз указывая @Entity помнить ещё и про xml.
Я тут для тестов одного функционала создал десяток сущностей — ваше минимальное неудобство не такое уж и минимальное.

Вообще замечание вполне резонное. Более того, такое в платформе было и привело к достаточно долгой процедуре скана на старте приложения. У нас есть планы вернуть такой подход, при котором будет сканироваться определенный package, указанный разработчиком.
Version ставится над полем, в 90% случаев, я думаю, это поле будет называться version и дальше про него все забудут. Зачем нужен бойлерплейт?
То же самое можно сказать про @CreatedDate и @LastModifiedDate.

С доводом относительно version можно согласиться, а вот на счёт Creatable и Updatable я совсем не согласен.
Spring предполагает (по именам аннотаций) поля createdDate, createdBy, lastModifiedDate и lastModifiedBy. Причём в любом количестве и всё же с любыми именами.
Я предпочитаю createdAt, createdBy, updatedAt и updatedBy.
CUBA же жёстко заставляет использовать конкретно и только createTs, createdBy, updateTs и updatedBy.
Причём только по 2 вместе. То есть я не могу контролировать только даты — если я хочу дату я должен дать и пользователя.
Более того у CUBA автор изменений это только строка. В Spring это может быть любой класс и я использовал entity-класс пользователя — консистентность, гибкость, удобство, круть. А тут — строка. Консистентность? Гибкость? Удобство? Хм…
Это не говоря о том что дата создания изменения это строго java.util.Date. JSR 310: Date and Time API — не не слышали :(


Зачем нужен бойлерплейт?

А его реально много?
Вот это без одно поле в базовом классе без Lombok:


@Entity
@MappedSuperclass
public class SomeBaseEntity {
    @NotNull
    @CreatedDate
    private LocalDateTime createdAt;

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
}

А вот так с Lombok:


@Data
@Entity
@MappedSuperclass
public class SomeBaseEntity {
    @NotNull
    @CreatedDate
    private LocalDateTime createdAt;

В любом случае это делается 1 раз в базовом классе.
Я вот не уверен что цена которую требует CUBA за уничтожение бойлерплейта (жёсткие имена полей, странные типы данных) стоит того объёма бойлерплейка который будет убран

Я не против таких доводов и не говорю, что Spring или Lombok плохо, а CUBA — хорошо. Мое мнение — если надо быстро сделать типовое приложение и всем будет все равно, как называются поля для аудита в БД, если их назначение понятно, то на CUBA это будет быстрее и, скорее всего, меньше кода. Пара интерфейсов в базовом класе — и готово. Если надо более сложных вещей, то есть Entity Listeners, там много чего можно навернуть.

Ну не знаю. Мне, например, не всё равно ни на имена полей ни на их тип. (String, Карл, String!)

Кроме того, скрипты SQL, которые генерирует CUBA, делаются в виде файлов и можно посмотреть, что было сгенерировано и даже поправить руками или дописать свое, если требуется, перед тем, как применять изменения. Это не черный ящик. Скрипты SQL попадают в codebase, коммитятся в Git и они вообще часть проекта.

А вот это уже хорошо.

А мне вот не нравится Lombok. И хотелось бы иметь еще какие-то способы кроме Lombok достигать похожих эффектов. Хорошо что они, эти способы, хоть где-то имеются.

А вообще лучше расскажите чем CUBA лучше чем Vaadin (свежее на русском, причём в вашем же блоге):


  • Чистая Java
  • Spring
  • Нет специфических слоёв доступа к данным
  • Правда авторизацию, скорее всего, нужно будет писать самому, но один раз за проект и вообще можно из проекта в проект таскать

В общем как мне кажется, у Vaadin те же плюсы (и даже больше), зато нет минусов CUBA.

Vaadin — это только UI, никакой инфраструктуры, не говоря уже про кэширование данных, кластер, права доступа и hot-deploy. В CUBA упор делается на скорость разработки типовых вещей, чтобы у вас осталось время и желание решать свои сложные и интересные задачи, а не в очередной раз прикручивать Spring / Hibernate / Vaadin / FlyWay / etc.

Прикрутить Spring / Hibernate / FlyWay занимает один вечер неспешного кодинга. А дальше решайте свои задачи

Остается ещё написать админку с пользователями и ролями, сконфигурировать Spring Security, написать Entity-DTO преобразования, сверстать шаблон для главного окна приложения, сделать ролевой доступ к пунктам меню, сделать кэш данных и запросов, постраничный вывод данных, форму фильтрации. Потом ещё библиотеку репортинга вкрутить и добавить формы ввода параметров отчета. И да, если этот продукт будет коробочным, то ещё будет немного веселья с кастомизацией для разных заказчиков, нужно будет придумывать, как правильно это делать с наименьшей болью.

Vaadin, EclipseLink, Spring уже собраны вместе в платформе. Не надо тратить вечер неспешного кодинга на их прикручивание. При разработке на CUBA эти фреймворки и используются, приемы разработки там те же.

Нет, если мы говорим про шаблонный конструктор неких бизнес-проектов под копирку — тогда ваша сборка наверное будет попроще. Тут ведь надо понимать, что чем уже специализация конструктора — тем профитнее его использовать для подходящих кейсов, но тем меньше становится этих самых кейсов. Я сначала из статьи подумал что это конкурент спринг бута, а это просто "сборка из модулей" для решения еще более узкого круга задач

Согласен с APXEOLOG — собрать вместе Spring Boot, Hibernate, Flyway/Liquibase, REST занимает максимум вечер. Ещё чуть-чуть времени займёт авторизация.
Всё не так страшно как вы описываете.

Vaadin — это только UI, никакой инфраструктуры, не говоря уже про кэширование данных, кластер, права доступа и hot-deploy.

Инфраструктура обеспечивается Spring и Spring Boot.
Кеширование им же и Hibernate.
Про кластеризацию не скажу — не было нужды.
Права доступа — есть и в Vaadin-е, плюс Spring.
Hot deploy обеспечивается JVM, правда если не сильно меняли классы. А CUBA может в hot deploy при изменении интерфейса классов?

Кеширование им же и Hibernate.

Я же говорю, это не противопоставление, это дополнение. На включение кэша в CUBA уйдет не больше времени, чем если вы это будете делать вручную. Причем я в статье написал, что как раз можно использовать спринговый @Cacheable.

Права доступа — есть и в Vaadin-е, плюс Spring.

Вот тут есть риск выйти за вечер неспешного кодинга, мне кажется. Особенно, если это делать в первый раз. В CUBA в готовой админке можно сразу выдавать права доступа на формы, сущности и атрибуты.

Hot deploy обеспечивается JVM, правда если не сильно меняли классы. А CUBA может в hot deploy при изменении интерфейса классов?

Конечно, же, не все можно сделать через hot deploy. Даже JRebel не всемогущ. Подробно тут: doc.cuba-platform.com/manual-latest-ru/hot_deploy.html, чтобы комментарии не пухли.
Я же говорю, это не противопоставление, это дополнение.

Ну вообще-то пост называется Разработка на CUBA — большой шаг в сторону от Spring? и это выглядит именно как противопоставление.


Да и отвечал я на комментарий jreznot про Vaadin.

Ну вообще-то пост называется Разработка на CUBA — большой шаг в сторону от Spring? и это выглядит именно как противопоставление.


Заголовок — да. В статье я постарался показать, что не так страшен новый фреймворк, как его малюют. И таки шаг в сторону небольшой, все равно Spring пользоваться, в основном. Значит, не очень мысль донес.
Идеи примерно такие же, да. jHipster можно рассматривать как конкурента. Был ещё такой забытый проект AppFuse, тоже про генерацию заготовок. Но CUBA добавляет туда возможность надстройки и кастомизации, поэтому она «платформа», а не «генератор заготовок приложения». Можно сходить по ссылкам в п.2 раздела «Итого», там как раз про расширяемость.

Ага, а потом разгребай баги еще и этого. Платформ над спрингом вагон и глюков там немаленькая тележка.

А всякое дао генерится нетбинсами и прочими штуками автоматом, ломбоки избавляют от гетеров и вообще хибернейт спокойно все решает с кэшами, плюс редис и спринг кэш.

Я писал, что мы сами используем платформу для разработки как коробочных продуктов, так и для софта на заказ. Так что команда разработчиков CUBA кровно заинтересована, чтобы багов было как можно меньше, иначе коллеги могут багрепорт с ноги сделать. Да, баги есть, куда же без них, только я не уверен, что при разработке такой же функциональности собственноручно их не будет.

По образцу того, как я делал Pet Clinic, можно ради эксперимента сделать приложение из CUBA учебника — Bicycle Workshop и посмотреть, сколько кода получится и сколько времени займет разработать это на Spiring/Spring Boot или ещё чем с такой же функциональностью.

Вот ведь как люди мучаются без Grails ;)

Чего это сразу «мучаются»? :-) Надо таки сравнение провести будет, только надо аккуратно метрики выбрать, по которым сравнивать, чтобы не забыть ни фичи CUBA, ни фичи Grails. Желательно на примере разработки приложения какого-нибудь. Если есть предложения, на каком примере это можно сделать — готов выслушать. Вышеупомянутый Bicycle Workshop пойдет, как думаете?
Мне кажется, Grails отлично подходит для двух вещей:
1) Разработка небольших и недосредних проектов, ну, условно, не более 50 контроллеров, 100 представлений (view), 50 доменных классов.
2) Поддержка непрофессиональными программистами.

У нас по работе программирование — не основной профиль. Но личным примером удалось заразить коллег, теперь 3-4 человека пишут на Groovy. Java точно не зашла бы.

И как лабать класс/котроллер/view удалось за пару часов. А уж Spring, пусть и boot — я бы постеснялся показывать просто.

Вот мои KPI — или groovy/grails, или мои коллеги так бы решали свои интеграционные задачи в лучшем случае на VBScript :)

Ну а серьёзно — думаю, сравнивать смысла нет. Groovy/Grails вылетели с хайпового горизонта, и постепенно уйдут в небытие…

А есть где-то приложение развернутое? Тянуть, собирать, развертывать мне как-то лень, а вот с уже задеплоеной версией я бы поигрался.
Тут много негативных отзывов про велосипедостроительство. Хочется разбавить их противоположным мнением.

Фреймворк — это сильно больше, чем набор его элементов.

Нет вообще никаких проблем склеить на синюю изоленту всякие Spring Boot, Spring Security, Hibernate, Liquibase, и написать админку пользователей за следующий вечер тоже проблем нет.

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

Если кто-то предлагает фреймворк, ну уж точно там ценность не в составе persistence.xml =) Ценность в опыте. Чтобы такой опыт получить, надо взять какую-то свою связку компонентов и сделать на ней хотя бы несколько проектов, а лучше — несколько десятков или сотен. Каждый проект будет полировать фреймворк и связанные с ним способы работы, как вода точит камень. При этом фреймворк-то может и не изменится почти кроме разных тонких мелочей, которые как раз этот опыт отражают.

И кстати, тут прямо в комментариях есть живой источник этого опыта. Про который, собственно, и можно спрашивать, вместо того чтобы пытаться загнобить автора ;)

По сабжу — авторы молодцы, жгите ещё!
Спасибо :-)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий