2021-й год закончился, уже почти прошел первый месяц 2022-го. Прошлый год стал знаменательным для JPA Buddy: первый публичный релиз, встреча с первым пользователем и рост до одного из самых высокорейтинговых плагинов на IntelliJ IDEA Marketplace. А еще завтра у Баддика первая годовщина — ровно год назад вышел первый публичный релиз! В этой статье мы решили поделиться историей, которая стоит за JPA Buddy, достижениями 2021-го года, некоторыми интересными фактами, которые получили от нашего комьюнити, и планами на 2022-й.
История
Для начала пара слов о том, как появился JPA Buddy. Идея плагина для IntelliJ IDEA появилась в 2019 году и она уходит корнями в другой продукт – Jmix (бывший CUBA Platform). Jmix – это фреймворк и прилагающийся к нему инструментарий для быстрой разработки бизнес-приложений. Как можно догадаться, слой доступа к данным в Jmix построен поверх JPA и инструмент разработки – Jmix Studio – позволяет построить модель данных (JPA сущности) при помощи визуального дизайнера практически без написания кода.
Этот визуальный дизайнер стал одной из самых любимых фич Jmix Studio, но его можно было использовать только для разработки приложений на фреймворке Jmix. И очевидно, что это сильно ограничивало круг разработчиков, которые бы хотели использовать визуальные инструменты IDE для работы с JPA в своих проектах. В итоге, мы решили выделить эту функциональность в отдельный плагин для IntelliJ IDEA, чтобы облегчить работу всем, кто использует JPA.
Разработка и преодоление трудностей
JPA – обширная и всеобъемлющая спецификация. Как уже было сказано, JPA Buddy основывался на функциональности Jmix Studio, в ней мы поддерживали довольно ограниченное подмножество фич из спецификации. Очевидно, что поддержка всех аспектов практически невозможна, особенно силами команды из двух разработчиков. Нам пришлось изучить спецификацию от корки до корки и сделать около сотни опросов, чтобы лучше понять, чем именно пользуется большинство разработчиков.
Для спецификации JPA есть несколько имплементаций. Не секрет, что Hibernate занимает доминирующее положение в этом семействе, но его доля далека от 100%. То же самое можно сказать о Spring с его проектом Spring Data JPA – доминирует, но не занимает весь рынок; у нас ещё есть Micronaut, Java EE/Jakarta EE, Eclipse Microprofile и основанные на нем фреймворки: Quarkus, Helidon и т.д. Проблема в том, что для этого многообразия фреймворков JPA Buddy должен генерировать код исключительно в контексте текущей имплементации JPA. Также генерируемый код определяется сопутствующими библиотеками приложения: Lombok, Hibernate Types, MapStruct... не говоря уже о выборе самого языка Java или Kotlin. Научить Баддика всем этим трюкам в условии суперпозиции всех условий было не очень просто, но вполне реально.
Изначально внешний вид дизайнера сущностей мы взяли из Jmix Studio. Он был разработан для тех, кто не был знаком с JPA (да и даже с Java не очень), но свою задачу выполнял хорошо. Но в процессе сбора обратной связи сразу стало ясно, что аудитория JPA Buddy будет отличаться от пользователей Jmix – это будут профессиональные Java разработчики. Поэтому, в отличие от Jmix, JPA Buddy никогда не скрывает исходный код под окном визуального дизайнера. Плагин аккуратно предлагает свою помощь в создании кода в соответствии с парадигмами JPA, а генерация кода сопровождается визуальными визардами. В итоге разработчики могут использовать практически все возможности плагина, без необходимости знать и помнить эти возможности наизусть.
В завершение нужно упомянуть, что работа с существующим исходным кодом – та ещё проблема. JPA Buddy – помощник, а не хозяин. Инструмент может давать совет, но не исправлять код без вашего ведома. Нам пришлось делать генерацию кода такой, чтобы не притащить ненужные или неожиданные изменения в существующие исходники. Чтобы это стало возможным, мы «тренировали» JPA Buddy «понимать» код, написанный разработчиком. Это заняло достаточно много времени, пока мы учились разбирать и обрабатывать исходники так, чтобы при этом не ломать плагин.
Миссия
Когда мы поняли, что подход Jmix c его визуальными дизайнерами не соответствует ожиданиям целевой аудитории, мы решили явно обозначить основные цели создания JPA Buddy:
Сделать порог входа для разработчиков как можно ниже
Ускорить разработку в части JPA и всего, что с этим связано
Форсировать применение лучших практик, при условии выбранных разработчиком библиотек, языка и имплементации JPA
Что касается генерации кода и инспекций, то мы тщательно изучили предмет, чтобы быть уверенными, что все соответствует спецификации, документации и лучшим практикам. Здесь нужно сказать спасибо Eugen Paraschiv, автору baeldung.com, а также Vlad Mihalcea и Thorben Janssen – их статьи и видео о JPA, Hibernate и Spring Data бесценным источником информации для всего Java сообщества.
Итоги 2021 года
2021-был отличным годом для всей команды JPA Buddy. Давайте пробежимся по некоторым итогам:
Выкатили больше 25 релизов, 6 мажорных версий
Закрыли больше 800 тикетов
Количество загрузок в JetBrains Marketplace: больше 500 тысяч уникальных и больше 1.6 миллиона в целом
Из 95 отзывов на странице плагина 91 был на пять звезд, средний рейтинг – 4.9
Заслужили статус «Recommended Plugin для IntelliJ IDEA»
Запустили собственный youtube канал
Сделали четыре выступления:
Вместе с Антоном Архиповым из JetBrains провели вебинар по лучшим практикам и частым ошибкам при использовании JPA в Kotlin
Совместно с RedGate (компанией, поддерживающей Flyway) сделали доклад о проблемах при миграции баз данных
В компании с JUGRu Group обсудили правила, которым мы следовали при разработке JPA Buddy
Написали больше 100 страниц документации
Получили больше 1500 сообщений в нашем канале Discord
Опубликовали восемь статей в нашем блоге
Количество подписчиков в Twitter превысило 2022, из 110 стран, количество просмотров твитов за год – более трех миллионов
А теперь давайте вспомним всю функциональность, разработанную в 2021-м:
Визуальные дизайнеры для:
JPA сущностей
Spring Data JPA репозиториев
Liquibase Changelog-ов
Файлов SQL и миграций Flyway
Генерации DTO и поддержка MapStruct
Помощь в написании кода:
Поддержка Kotlin
Инспекции для проверки правильности определения сущностей
Инспекции для безопасного использования Lombok
Контекстно-зависимая кодогенерация, доступная по комбинации клавиш
Версионирование баз данных:
Автоматическая генерация Liquibase скриптов
Автоматическая генерация Flyway миграций
Подсказки и возможность отключения небезопасных миграций
Импорт схемы базы данных:
Генерация сущностей из таблиц
Добавление атрибутов на основе столбцов таблиц в БД
Кэширование схемы БД для удаленных серверов
Даже сложно поверить, что все это было сделано такой небольшой командой всего за год!
Изучение мнений сообщества разработчиков
JPA Buddy – всего лишь инструмент. Именно поэтому мы стараемся фокусироваться на том, чего хотят разработчики и не влезать со своим собсвенным мнением в чужие монастыри. В 2021-м году мы делали несколько опросов, результатами которых хотелось бы поделиться.
Lombok
Похоже, нет такого Java разработчика, который был бы равнодушен к Lombok’у. Его или любят или ненавидят (ещё есть немного тех, которые про него не слышали :)). Такое радикальное отношение подтверждается и тем фактом, что твит про Lombok стал самым просматриваемым в аккаунте JPA Buddy. Но, к сожалению, Lombok – это ещё и причина самого большого количества типовых ошибок при использовании в определении сущностей JPA. При реализации поддержки Lombok в JPA Buddy, мы набили много шишек. В итоге, помимо новой функциональности в плагине, появилась статья в блоге, в которой мы собрали все советы по использованию Lombok в JPA. Этот пост стал самым читаемым в 2021-м году. Суммарно публикация на DZone и в блоге набрала около 20 тысяч просмотров за апрель.
Kotlin
Мы анонсировали поддержку Kotlin в конце апреля 2021. На тот момент мы и не думали, что JPA Buddy будет поддерживать тандем из Kotlin и JPA примерно в 15% проектов. А ещё одним сюрпризом стало то, что было невозможно нагуглить более-менее полное руководство по использованию JPA в приложениях, написанных на Kotlin. Когда мы собирали материалы и практики по использованию Kotlin, было немного страшновато видеть, что почти на каждом ресурсе по использованию Kotlin с JPA были примеры кода, которые могли привести к серьезным проблемам в приложении. В некоторых примерах использовались data-классы, а в некоторых – closed классы. Мы решили это исправить и собрать все практики использования Kotlin c JPA в одной статье. Почти 10 тысяч разработчиков прочли этот материал, в нашем хит-параде эта публикация уверенно занимает второе место.
Помимо всего этого, мы также сделали несколько опросов в Twitter, ниже – интересные факты и выводы из этих опросов.
Что первично в определении модели данных?
В этом посте мы спросили сообщество на предмет того, что является источником истины для построения модели данных. Вышло так: 56% разработчиков сначала меняют таблички в базе, а затем синхронизируют изменения с JPA сущностями, в то время как 44% делают наоборот: сначала меняют модель JPA, а затем обновляют БД.
На тот момент в JPA Buddy уже была возможность генерации скриптов обновления БД. Это делалось путем сравнения JPA модели и базы данных – большое подспорье тем, для кого JPA модель первична. Но получалось, что более половины разработчиков не могли полноценно пользоваться JPA Buddy для генерации обновлений из БД.
Это привело к решению назначить наивысший приоритет задаче импорта схемы данных в JPA модель, и мы даже пересмотрели свой взгляд на то, как это должно выглядеть в продукте. До опроса импорт представлялся как одноразовая операция: разработчик импортировал бы схему данных в JPA модель на начальном этапе разработки проекта, и работал бы дальше только с ней. Результаты опроса показали, что разработчики используют импорт постоянно, после каждого изменения таблиц в базе. Таким образом, было принято решение использовать подход, при котором таблицы (и даже поля) импортировались бы в JPA модель по одной, позволяя пользователю выбирать только необходимые изменения, без перегенерации всего кода JPA сущности.
Надеемся, что JPA Buddy теперь отвечает требованиям обоих лагерей разработчиков: и тем, у кого база – источник истины и тем, у кого это – JPA модель.
Flyway vs Liquibase
Сейчас JPA Buddy позволяет генерировать скрипты обновления БД и для Liquibase, и для Flyway, однако, в первых версиях мы предлагали поддержку только для Liquibase. Чтобы понять, насколько приоритетна задача поддержки Flyway, мы запустили следующий опрос:
Как видно, в Java сообществе Flyway выигрывает. После анализа комментариев к опросу, были сделаны следующие выводы:
Люди выбирают Liquibase из-за возможности отката изменений, загрузки данных из CSV, preconditions, labels и contexts.
Основное преимущество Flyway – очень понятная концепция и простота использования.
Некоторые все ещё верят, что обновление БД – не задача разработчика, а этим должен заниматься администратор базы данных…
Правильный маппинг для типа данных SQL Timestamp/Datetime
Когда мы разрабатывали функциональность импорта таблиц БД в объекты JPA, то нужно было делать отображение типов данных столбцов таблиц в Java типы. И угадайте, про какой тип данных мы спорили больше всего? Конечно же Timestamp/Datetime! Так и не придя к общему знаменателю, мы решили попросить совета у сообщества и сделали ещё один опрос:
Как видите, 63% проголосовали за LocalDateTime
. Ho! Спасибо Simon Martinelli и Corneil du Plessis, они первыми заметили, что правильного ответа здесь нет! Оказалось, что то, что нам было нужно – java.time.Instant
!
Планы на 2022
Начнем с того, что с 2022-го некоторые фичи JPA Buddy будут доступны только по подписке. Весь год разработка плагина велась на энтузиазме и финансировалась изнутри компании. Спасибо Haulmont за то, что весь 2021 год мы смогли сохранять JPA Buddy полностью бесплатным. Однако, в 2022 мы всё же хотим получить канал стабильного финансирования, чтобы развивать плагин не по остаточному принципу, а более интенсивно. Ориентируемся на 1 апреля. Мы выбрали freemium модель: большая часть функциональности будет бесплатной, включая все визуальные редакторы для сущностей, Spring Data репозиториев, Flyway и Liquibase скриптов. Автоматическая генерация скриптов версионирования для Liquibase и Flyway, а также импорт схемы данных в JPA станут платными: 1,9$ в месяц для индивидуальных пользователей. JPA Buddy останется бесплатным для студентов и для академического использования, а также для обучающих курсов и школ программирования. Также мы предлагаем скидку 50% для учебных и некоммерческих организаций. Мы уверены, что наш инструмент экономит большое количество времени, и пара долларов в месяц окупится уже через несколько дней, если вы будете использовать JPA Buddy.
Во-вторых, мы планируем финализировать функциональность импорта таблиц БД в JPA, чтобы поддерживать не только импорт одиночных таблиц, но и пакетные операции. В идеале нам бы очень хотелось сделать так, чтобы можно было создавать приложение целиком на основе только лишь базы данных: вы указываете схему, а JPA Buddy генерирует все сущности, репозитории и даже REST контроллеры для CRUD операций.
В-третьих, мы планируем новую функциональность: «smart hints» - умные подсказки. Разработчики будут видеть различные советы, которые помогут сделать ваше приложение лучше, например, подсказки для более эффективного маппинга или рекомендации для оптимизации выборки данных.
А в багтрекере у нас ещё есть много того, над чем можно подумать. Мы будем приоритезировать всю эту функциональность в соответствии обратной связью и постепенно добавлять в наш плагин.
Мы видим следующий год ещё более продуктивным! Надеемся, COVID в конце концов покинет нас в 2022-м и мы сможем опять путешествовать по миру, видеться в офлайне, обмениваться идеями, как сделать софт лучше, а разработку – приятнее. Мы благодарим все пятьсот тысяч разработчиков, которые попробовали JPA Buddy в 2021-м году и дважды благодарим тех, кто сообщал нам об ошибках или делился своими соображениями и идеями.