В Hibernate есть возможность определить правила именования для всех автоматически создаваемых таблиц для классов предметной области. Обычно такие правила сводятся к присоединению определённых префиксов или постфиксов к именам таблиц. Также можно проверять имена создаваемых таблиц на соответствие корпоративным правилам и т.п.
Создадим класс предметной области следующего содержания:
1 2 3 4 5 6 |
@Entity public class UserProfile { @Id @GeneratedValue Long id; } |
Создадим бин PhysicalNamingStrategy, который и будет определять правила создания имён таблиц. Для простоты сделаем это в главном классе приложения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
@Bean public PhysicalNamingStrategy physicalNamingStrategy() { return new PhysicalNamingStrategy() { @Override public Identifier toPhysicalCatalogName(Identifier logicalName, JdbcEnvironment jdbcEnvironment) { return logicalName; } @Override public Identifier toPhysicalSchemaName(Identifier logicalName, JdbcEnvironment jdbcEnvironment) { return logicalName; } @Override public Identifier toPhysicalTableName(Identifier logicalName, JdbcEnvironment jdbcEnvironment) { return new Identifier("PREFIX_" + logicalName.getText(), logicalName.isQuoted()); } @Override public Identifier toPhysicalSequenceName(Identifier logicalName, JdbcEnvironment jdbcEnvironment) { return logicalName; } @Override public Identifier toPhysicalColumnName(Identifier logicalName, JdbcEnvironment jdbcEnvironment) { return logicalName; } }; } |
Каждый из методов интерфейса PhysicalNamingStrategy, который мы имплементируем (возвращая анонимный класс), совершенно прозрачно описывает своё назначение.
Поскольку нам нужно обработать имена таблиц, то мы вносим соответствующие изменения в метод toPhysicalTableName. Этот метод (как впрочем и другие) принимает в качестве параметра объект типа org.hibernate.boot.model.naming.Identifier, в котором есть два поля:
- text — с названием таблицы до всякой (даже стандартной) обработки;
- isQuoted — булево поле, показывающее, заключено ли название в кавычки, например, в аннотации:
@Table(name = "\"USER\"")
.
Из второго параметра org.hibernate.engine.jdbc.env.spi.JdbcEnvironment можно получить различные метаданные СУБД.
Из метода мы должны вернуть объект того же типа Identifier, только настроив поля text и isQuoted нужным нам образом. В нашем примере к названию таблицы мы прибавляем префикс PREFIX_, а флаг кавычек оставляем как был.
В результате схема БД будет выглядеть следующим образом:
Обратите внимание, что:
- Поскольку мы используем кастомный класс PhysicalNamingStrategy, в котором задаём кастомное преобразование имени таблицы из класса, в фактическое имя таблицы, то стандартное преобразования из имени класса с кемел кейсом в имя таблицы с нижнем подчёркиванием не происходит. То есть никто нам из UserProfile не сделает USER_PROFILE, если мы сами этого не сделаем.
- Имя сиквенса для id-поля этой таблицы будет создано уже на основе нашего кастомного имени таблицы. Если мы хотим ещё как-то повлиять на имя сиквенса, то мы можем это сделать в переопределяемом методе toPhysicalSequenceName. Отметим, что этот метод параметр Identifier приходит с уже изменённым именем таблицы с постфиксом _SEQ:
Также при необходимости в методе toPhysicalTableName (как в принципе и в других) можно проверять соответствие названия таблицы тем или иным требованиям. Если название не соответствует, то можно выбрасывать исключение. Такое исключение не позволит приложению подняться и несоответствие требованию будет выявлено на ранней стадии, ещё до начала процесса выполнения программы.