Чем ближе вы (используя генератор) к своему сценарию использования, определите пользовательский генератор.
Пример, доступный в https://www.baeldung.com/hibernate-identifiers:
Давайте создадим генератор, который создает идентификаторы, содержащие строку
префикс и номер:
public class MyGenerator implements
IdentifierGenerator, Configurable {
private String prefix;
@Override
public Serializable generate(
SharedSessionContractImplementor session, Object obj)
throws HibernateException {
String query = String.format("select %s from %s",
session.getEntityPersister(obj.getClass().getName(), obj)
.getIdentifierPropertyName(),
obj.getClass().getSimpleName());
Stream ids = session.createQuery(query).stream();
Long max = ids.map(o -> o.replace(prefix + "-", ""))
.mapToLong(Long::parseLong)
.max()
.orElse(0L);
return prefix + "-" + (max + 1);
}
@Override
public void configure(Type type, Properties properties,
ServiceRegistry serviceRegistry) throws MappingException {
prefix = properties.getProperty("prefix");
}
}
>
В этом примере мы переопределяем метод generate () из интерфейса IdentifierGenerator и сначала находим наибольшее число из
Существующие первичные ключи вида префикс-XX.
Затем мы добавляем 1 к максимальному найденному числу и добавляем префикс
свойство для получения вновь созданного значения идентификатора.
Наш класс также реализует интерфейс Configurable, так что мы можем
установите значение свойства префикса в методе configure ().
Далее, давайте добавим этот пользовательский генератор к сущности. Для этого мы можем
используйте аннотацию @GenericGenerator с параметром стратегии, который
содержит полное имя класса нашего класса генератора:
@Entity
public class Product {
@Id
@GeneratedValue(generator = "prod-generator")
@GenericGenerator(name = "prod-generator",
parameters = @Parameter(name = "prefix", value = "prod"),
strategy = "com.baeldung.hibernate.pojo.generator.MyGenerator")
private String prodId;
// ...
}
Также обратите внимание, что мы установили параметр префикса «prod».
Давайте посмотрим быстрый тест JUnit для более ясного понимания идентификатора
сгенерированные значения:
@Test
public void whenSaveCustomGeneratedId_thenOk()
{
Product product = new Product();
session.save(product);
Product product2 = new Product();
session.save(product2);
assertThat(product2.getProdId()).isEqualTo("prod-2");
}
Здесь первое значение, сгенерированное с использованием префикса «prod», было «prod-1», а затем
«Прод-2».
Другой альтернативой может быть использование составного ключа (спецификация JPA):
Составной первичный ключ должен соответствовать либо одному постоянному
поле или свойство или набор таких полей или свойств, как
описано ниже. Класс первичного ключа должен быть определен для представления
составной первичный ключ. Составные первичные ключи обычно возникают, когда
отображение из устаревших баз данных, когда ключ базы данных состоит из
несколько столбцов. Используются аннотации EmbeddedId и IdClass.
для обозначения составных первичных ключей. См. Разделы 9.1.14 и 9.1.15.