Java Developer
  • Как использовать Hibernate: основные проблемы и их решения

    Я в этой ветке dou.ua/...​to-use-hibernate/#1581522 привёл свои аргументы

  • Как использовать Hibernate: основные проблемы и их решения

    Классический ответ таков — JPA отражает доменную область на БД без написания sql вручную.
    Т.е. можно свободно оперировать объектами:

            Order order = new Order(
                    new Address("Kiev", "Shevchenko av.", "1"),
                    new Client("Mykola", "Gurov")
            );
            Item item1 = new Item("aaa", Money.of(100, "USD"));
            order.addItem(item1);
            em.persist(order);
    
    Потом делать
            Item item2 = new Item("bbb", Money.of(50, "EUR"));
            order.addItem(item2);
            order.addItem(item1);
    
    ... и Hibernate выполнит все нужные insert-ы и update-ы и расставит id-шники.

    * совсем маленький нюанс stackoverflow.com/...​ate-using-jpa-annotations

  • Как использовать Hibernate: основные проблемы и их решения

    Т.е. если так сложилось, что entities «угадываются» для существующей таблицы, будь то Oracle с NUMBER(1), или Postgres с BOOLEAN, или MySql с BIT(1) — во всех случаях удобнее, если в джаве будет

    private boolean express;
  • Как использовать Hibernate: основные проблемы и их решения

    Я конечно понимаю что случай «самый тяжелый», но это вещь специфична. Как бы здесь камень преткновения между абстрактной БД и ньюансами реализации в, к примеру, Oracle.

    Здесь нет камня преткновения для абстрактного JPA, который работает с абстрактной БД.
    Тяжелым случаем его делает разработчик, который глядя на Oracle с полем Number(1), пишет
    private Integer express;
    вместо
    private boolean express;

    Вы просите объяснить преимущества инкапсуляции перед POJO?
    Прошу объяснить откуда она прилетела в статью.

    en.wikipedia.org/...​on_(computer_programming

  • Как использовать Hibernate: основные проблемы и их решения

    Попробую перефразировать начало статьи другими словами.

    Речь вообще не о том, чтобы позволить приложению создавать схему на проде.
    Речь о том, что маппинг можно прокладывать с двух сторон.
    Либо создавать джава классы и

    разбираться с hibernate ньюансами для создания индексов, связей и ограничений,

    (их немного и они очевидны)
    ... смотреть на созданную схему и использовать её в flyway/liquibase.

    Либо вначале создавать таблицы, а потом под них угадывать entity.
    Я наблюдал много неудачных примеров второго подхода.

  • Как использовать Hibernate: основные проблемы и их решения

    По той же причине, по какой существуют другие браузеры, кроме встроенного в OS, например.
    Каждое решение:
    а) считает, что его реализация стандарта технически лучше конкурентов;
    б) добавляет свои уникальные фичи сверх стандарта.

    Статья на 99% о JPA без привязки к конкретному провайдеру.

    Поддержал: Андрей Плотников
  • Как использовать Hibernate: основные проблемы и их решения

    А Oracle, к примеру — не имеет. Но это не значит, что в entity следует использовать Integer.
    Если в примере абстрактная БД это Oracle, то это лучше упомянуть. В статье.

    Ок. Я объясню. В программировании предпочтительнее оперировать стандартами (интерфейсами), а не конкретными реализациями. Поэтому, какой бы провайдер JPA вы не выбрали (Hibernate, EclipseLink и т.д.), и какая бы реляционная БД не была (Oracle, Postgres, MySql и т.д.) есть такая фича. Можно указать поле private boolean express; и его значение правильно сохраниться в таблице, вне зависимости, есть в базе такой тип или нет.

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

    Немного растерялся, вы знакомы с понятием Enum? docs.oracle.com/...​ial/java/javaOO/enum.html

    Программист имеет возможность ошибиться и «использовать стринги вместо ссылок из Static класса», а enum не позволит скомпилировать такой код.

    Что возращает меня к вопросу: почему? Точнее, в чем преимущества перед привносимыми недостатками: boilerplate code:
    Здесь нет наследования, инкапсуляция порождает boilerplate.

    Вы просите объяснить преимущества инкапсуляции перед POJO?
    И давайте уточним, одинаково ли мы понимаем слова boilerplate code. Вы что в них вкладываете в этом примере?

    есть вещи которые не стоит использовать в продакшене.

    Какие?

    Опять таки, не указан стэк, приходиться догадываться что:

    Зачем указывать стэк?! Повторюсь,

    Все описанные проблемы (см. список в конце статьи) имеют место быть в Java Persistence API независимо от реализации.
    Мы о каких-то разных ООП говорим?

    Судя по всему, да. Java — объектно-ориентированный язык программирования. Java Persistence API — о том, как эти самые объекты хранить в БД.

    для кого статья написана?

    Для тех, кто понимает суть поднятых вопросов.

  • Как использовать Hibernate: основные проблемы и их решения

    Вы снова невнимательны.
    Я же два раза уточнял

    Поскольку при разработке приложения структура классов меняется, созданная JPA схема — это, скорее, заготовка для flyway/liquibase и/или in-memory БД.
    2) последующие изменения структуры классов/таблиц тоже к вопросу не относятся.

    Я говорю о create, а не о update.

  • Как использовать Hibernate: основные проблемы и их решения

    А этот момент давайте отдельно.

    (ответ: создавать схему которую автоматически генерируют на продакшене — не лучшая идея)

    Тут я спрошу «Почему?» Какие аргументы против?

    Сразу за скобки вынесем, что:
    1) приложению права на DDL в БД обычно не дают,
    2) последующие изменения структуры классов/таблиц тоже к вопросу не относятся.

  • Как использовать Hibernate: основные проблемы и их решения

    PostgreSQL, к примеру, как и другие SQL, имеет тип boolean, так что проблема не в переносе в джаву.

    А Oracle, к примеру — не имеет. Но это не значит, что в entity следует использовать Integer.

    легко ошибиться со значениями поля status;
    каким образом?

    Если для поля status использовать String, то можно приосвоить произвольное значение, если enum — только определённые.

    для денег вполне подходит BigDecimal,
    у товара есть неизменная цена с валютой;

    Вы невнимательно читали статью? Или хотите подискуссировать на тему класс vs отдельные поля? Свои аргументы я привёл в этой ветке dou.ua/...​to-use-hibernate/#1581031

    С учетом базового принципа «Класс должен уметь работать без JPA» лучше:
    Почему?

    Знакомы с понятием инкапсуляции?

    Опять таки, непонятно для кого статья.
    поскольку идет обучение конкретно Hibernate

    Это не обучение. Делюсь опытом и проблемами с коллегами. В этой ветке dou.ua/...​to-use-hibernate/#1580909, например, обсуждалась эквивалентность объектов.

    Самое странное для меня. Уже давно есть Spring Data JPA.

    Все описанные проблемы (см. список в конце статьи) имеют место быть в Java Persistence API независимо от реализации.

    могу сказать что «о чем пишете» знаете, но выразить это не получилось.

    В комуникации всегда есть две стороны.

    Давайте я вам в качестве ответной любезности верну — такое чувство, что комментатор не понимает о чём статья, потому что работает только со Spring Data и POJO не зная об ООП.

    PS: у Вас были проекты где нельзя было использовать Spring Data?

    Да, например, JEE + Glassfish + EclipseLink. Ещё раз — всё в статье о JPA, независимо(*) от провайдера.

    * — в статье есть один Hibernate-специфичный нюанс

  • Как использовать Hibernate: основные проблемы и их решения

    Я задал эти вопросы, потому что у меня недоумение.

    Выше выше утверждаете, что строите дтошку вне сессии. А границы транзакций на сервисах. Этим, мне кажется (поэтому я и переспрашиваю), создаются следущие проблемы:
    — lazy-loading либо бросает LazyLoadingException либо вызывается вендор-специфичным Hibernate.initialize();
    — для нескольких entities приведённый код
    X x = xService.get(xId); Y y = yService.get(yId);
    может вернуть неконсистентную дто из-за 2 транзакций.

    Почему вы не строите дто в сессии?

    Преобразованию во вью нечего делать в сервисном слое.
    Потому что сервисы и представление должны быть разнесены.

    Абсолютно верно. Но почему транзакции на сервисе, а не на фасаде?

  • Как использовать Hibernate: основные проблемы и их решения

    Это не правило, это следствие использования суррогатного ключа. Тем не менее, проверять transient ли объект нужно не через id == null, а через entityManager.contains()

  • Как использовать Hibernate: основные проблемы и их решения

    clients = Client.includes(:address)
    
    SELECT * FROM clients LIMIT 10
    SELECT addresses.* FROM addresses
      WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
    

    Ті самі яйця, вид сбоку — lazy + а-ля fetch join/entityGraph. Плюс, так розумію, можлива додаткова проблема через ліміт кількості в IN.

  • Как использовать Hibernate: основные проблемы и их решения

    «Любая дискуссия в интернете постепенно скатывается на личности, поэтому чтобы сэкономить время, начну сразу с них»?

    Поддержали: Serhii Nykyforov, Mykola Makhin
  • Как использовать Hibernate: основные проблемы и их решения

    Задачка на внимательность — что в моём примере является Hibernate specific?

  • Как использовать Hibernate: основные проблемы и их решения

    Для геттерів і сеттерів є Lombok.
    Дозволь поцікавитись: що в Rails придумали на тему lazy, eager, fetch join, entityGraph і всього іншого лайна, про яке ми тут сперечаємось?

  • Как использовать Hibernate: основные проблемы и их решения

    Разрешите полюбопытствовать: почему так?
    Где у вас рамки транзакции?
    Как строится дто из нескольких entities?

  • Как использовать Hibernate: основные проблемы и их решения

    Конечно, про сиквесны в бд. Хибовские потому что они в бд так и называются, hibernate.sequence :)

    Да, с сиквенсами есть проблемы при вставке большого количества данных.
    Извлекать значения по одному — медленно.
    Извлекать значения пачками — есть нюансы vladmihalcea.com/the-hilo-algorithm
    Я поэтому и подумал, что uuid в конструкторе решает эти проблемы.

    Но в целом, конечно, правильно чтобы в транзиент объекте ид было нулл.

    Такого требования нет.

    Вопрос в том, что «замедление» может быть столь ничтожным, что им можно пренебречь.

    Что-то никак не получается объяснить, что я имею в виду. «Свободный» поиск по полям Сlient c помощью CriteriaBuilder-а выльется в запрос select * from client where first_name like '%str%' or last_name like '%str%'. Если у класса уже была eager-коллекция, то получаем N+1 проблему, которая замедлит этот поиск.

  • Как использовать Hibernate: основные проблемы и их решения

    Дтошка строится вне сессии?

  • Как использовать Hibernate: основные проблемы и их решения

    Мани — часть апи с большим количеством логики

    Давайте называть это всё таки классом.

    Правильно ли я понимаю, что мы сейчас сравниваем «процедуры + структуры» vs «классы + JPA» и оба предпочитаем второе?

    Увы, из-за засилья POJO неочевидно, что в Address конечно же появится логика.

← Сtrl 123456...12 Ctrl →