Использование аннотации @Entity для решения конфликтов имён в JPA запросах при наличии классов предметной области с одинаковыми именами

Может так сложиться, что в проекте будет некоторое количество классов предметной области с одинаковыми именами, но расположенные в разных пакетах. Например, два класса Client. Им могут быть сопоставлены разные таблицы, но в JPA запросах вида «select c from Client c» будет иметь место неоднозначность. Чтобы эту неоднозначность снять, можно воспользоваться параметром name аннотации @Entity.

В пакете external создадим следующий класс предметной области:

В пакете internal создадим парный ему класс с таким же названием:

Обратим внимание на то, что параметре аннотации @Entity в одном случае мы указали ExternalClient, а во втором — InternalClient. Теперь в JPA запросах мы можем различать эти две сущности с помощью заданных имён.

Проверим, что это действительно так.

Создадим файл package-info.java следующего содержания:

Такой подход позволяет создавать именованные запросы на уровне пакета. Здесь для простоты мы создадим только один именованный запрос, который будет обращаться к сущности com.demo.app.internal.Client, поскольку в самом JPA запросе мы ссылаемся на InternalClient, а именно у com.demo.app.internal.Client стоит аннотация @Entity(name = "InternalClient").

Создадим бин репозитория:

Создадим тест, который докажет, что именованный запрос работает так, как ожидается:

Если тест вдруг провалится, то убедитесь, что вы правильно переопределили методы equals() и hashCode().

В тесте мы создаём объект типа com.demo.app.internal.Client и сохраняем его в базу. Затем делаем выборку с помощью именованного запроса «select i from InternalClient i». И действительно, запрос находит то, что мы и ожидаем. Никакой путаницы между классами internal.Client и external.Client не возникает, несмотря на то, что у них совпадают имена.