Comments 9
Спасибо за статью. Пара имхо замечаний:
генерировать схему БД с помощью hbm2ddl - плохая идея (создавать схему самому не дольше по времени, если есть навыки работы с БД, зато несравнимо лучше по качеству, эффективности и чистоте кода(нет нужды описывать кучу ненужных в сервисе констрейнтов на уровне классов модели)), но валидировать вполне.
а описывать все скрипты по созданию схемы лучше сразу в виде миграции (Liquibase, Flyway, etc.)
mappedBy свойство не имеет отношения к генерации схемы, оно указывает как работать с сущностями при ORM-маппинге. Если указано над entity, то его поле с указанным именем используется для связи с текущей entity при маппинге. А уже встроенный механизм hbm2ddl при его активации парсит эти свойства и применяет при генерации
аналогично для @JoinColumn - ее свойство value лишь указывает на имя колонки в БД, на которую осуществляется маппинг текущего поля при работе с entity. Default namnig strategy также можно менять, но имя лучше явно указывать для наглядноси.
двусторонняя связь на уровне БД не может быть нужна. Как правило связь указывается в зависимой сущности.
непонятно, с какой целью в примере используется @Transactional - она не имеет реализованного функционала в чистом Hibernate, но даже при использовании, например, Spring реализаций, она ни к чему над этим методом.
в качестве naturalId лучше использовать не синтетические поля, а любое поле сущности имеющее констрейнт unique (типа username etc.). Синтетические поля вообще дурная практика - они просто засоряют логику и понимание кода.
деталь: над интерфейсом, наследующим JpaRepository нет смысла ставить @Repository
деталь: чтобы IDEA понимала твои маппинги, стоит добавить связь с твоей БД (для sql это тоже делается - Alt+Enter -> Inject language)
непонятно также, с какой целью автор описывал громоздкий именованный граф над сущностью и доставал сущности через find, если у него при этом очевидно используется Spring Data JPA на скрине выше, где к тому же очевидно используется свойство attrıbutePath, которое не работает с именованными графами. Т.е. как говорится, Вы либо крестик снимите, либо трусы наденьте.
BatchSize использовать можно не только над коллекциями. Можно поставить над типом entity(тогда все запросы сущностей с которыми связаны помеченные сущности в единичном экземпляре будут подтягиваться батчем)
использовать H2 - не лучшая практика, т.к. при тестировании луше использовать более схожую с боевой среду. Лучше использовать test containers
Простите за грубость, но я очень огорчён предложением использовать автогенерацию таблиц и H2
Отличная статья! Продолжай!
HashCode по дефолту вычисляется исходя из всех полей вашей сущности, и как следствие меняется при изменении любого поля.
HashCode по дефолту вычисляется исходя из нахождения ссылки в памяти.
Согласен, был не прав. Сейчас немного ознакомился с темой, и если я все правильно понял, то как минимум с шестой версии реализация по умолчанию hashCode в OpenJDK не имеет ничего общего с адресом памяти
Hibernate: заполняем пробелы