Параметр схемы Hibernate не работает в аннотации @SequenceGenerator
У меня есть следующий код:
@Entity
@Table(name = "my_table", schema = "my_schema")
@SequenceGenerator(name = "my_table_id_seq", sequenceName = "my_table_id_seq",
schema = "my_schema")
public class MyClass {
@Id
@GeneratedValue(generator = "my_table_id_seq",
strategy = GenerationType.SEQUENCE)
private int id;
}
База данных: Postgresql 8.4, аннотации Hibernate 3.5.0-Final.
При сохранении объекта MyClass он генерирует следующий SQL-запрос:
select nextval('my_table_id_seq')
Таким образом, префикс схемы отсутствует, поэтому последовательность не может быть найдена. Когда я пишу sequenceName как
sequenceName = "my_schema.my_table_id_seq"
все работает.
Есть ли у меня недоразумения по поводу значения параметра схемы или это ошибка? Любые идеи, как заставить параметр схемы работать?
Ответы
Ответ 1
Такая же проблема здесь выглядит как ошибка для меня. Я использую спящий режим 3.6.7
Посмотрев исходный код, я вижу метод org.hibernate.cfg.annotations.reflection.JPAOverridenAnnotationReader#buildSequenceGeneratorAnnotation(Element element)
, который, похоже, копирует значения атрибутов name
, sequence-name
, initial-value
и allocation-size
, но я не вижу ссылки на catalog
или schema
Я ожидал увидеть нечто похожее на метод getTable(Element tree, XMLContext.Default defaults)
(того же класса), который имеет
annotation.setValue("schema", table.schema());
annotation.setValue("catalog", table.catalog());`
или buildTableGeneratorAnnotation
, который имеет
copyStringAttribute(ad, element, "catalog", false);
copyStringAttribute(ad, element, "schema", false);
Итак, даже если немного хакерский, путь, по крайней мере, для этой версии, по-видимому, префикс sequenceName
, как вы говорите.
Ответ 2
Мое обходное решение выглядит так (JPA 2.1, Hibernate 4.3.8.Final, PostgreSQL 9.4):
@SequenceGenerator(name = "seq_name", sequenceName = "my_schema.seq_name", schema = "my_schema", allocationSize = 1, initialValue = 1)
Ответ 3
Это звучит как ошибка: поставщик JPA должен чтить "новый" (поскольку Java Persistence 2.0) schema
и catalog
атрибуты @SequenceGenerator
аннотация. Я предлагаю поднять вопрос Jira (проекты аннотаций и менеджеров сущностей теперь находятся в ядре), не удалось найти ни одного существующего.
Ответ 4
Такая же проблема, используя Hibernate 4.3.6.Final, с Spring 4.1.4.RELEASE, на Oracle Database 11g Enterprise Edition Release 11.2.0.1.0.
Похоже, что это ошибка = > https://hibernate.atlassian.net/browse/HHH-7232
Мы столкнулись с проблемой, создав синоним в схеме A, указывающий на последовательность в схеме B. Этот синоним был тем, что мы использовали в атрибуте схемы @SequenceGenerator аннотации
Ответ 5
Я решил эту проблему в postgresql 9.6, добавив только мою схему перед именем последовательности, например:
(before) sequence name: seq_area_tematica
(after) sequence name: sisbp.seq_area_tematica
И это работает. Смотрите код:
@Id
@Column(name="seq_area_tematica")
@GeneratedValue(generator="sequence",strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="sequence",sequenceName="sisbp.seq_area_tematica")
private Long id;
Смотрите "sisbp" перед sequenceName. Имя sequenceName было "seq_area_tematica" и теперь является "sisbp" (схема) + "seq_area_tematica".
Ответ 6
Хммм, я не очень часто работаю с внутренними системами спящего режима, но здесь есть информация:
https://forum.hibernate.org/viewtopic.php?p=2406761
Вы также можете установить схему по умолчанию для пользователя, подключающегося к PostgreSQL через ALTER USER... SET SEARCH_PATH
Ответ 7
Попробуйте переместить аннотацию SequenceGenerator из объявления класса POJO в объявление поля id. С Hibernate 3.6.4 это
@Entity
@Table(name = "my_table", schema = "my_schema")
public class MyClass {
@Id
@GeneratedValue(generator = "my_table_id_seq",
strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "my_table_id_seq", sequenceName = "my_table_id_seq", schema = "my_schema")
private int id;
}
создает это для MySQL
create table my_schema.my_table_id_seq (
next_val bigint
);
insert into my_schema.my_table_id_seq values ( 1 );
а для PostgreSQL
create sequence my_schema.my_table_id_seq start 1 increment 50;
Ответ 8
Использование Hibernate 4.2.0.Final
здесь и та же проблема. Похоже, это ошибка, на которую ответили другие пользователи. Я хотел использовать динамическую схему для последовательностей, в зависимости от схемы, установленной для сеанса, но для некоторых последовательностей я хотел использовать public
схему. Поэтому мне пришлось использовать предложенное вами решение: поместить имя схемы в имя последовательности, где я хочу использовать конкретную схему:
@SequenceGenerator(name = "my_table_id_seq", sequenceName="my_schema.my_table_id_seq",
schema = "my_schema")
Для случаев, когда я хотел использовать схему, установленную для сеанса, я использовал sequenceName
без предварительной схемы.
Для тех, кому нужна одинаковая схема для всех последовательностей, вы можете использовать свойство hibernate.default_schema
. При этом вам не нужно изменять свойства @SequenceGenerator
:
<prop key="hibernate.default_schema">my_schema_name</prop>
Я использую СУБД PostgreSQL. Если вы хотите динамически изменить имя последовательности, когда Hibernate вызывает nextval('my_sequence')
вы можете расширить свой класс диалекта базы данных и настроить использование Hibernate. Вам нужно просто переопределить getSequenceNextValString()
. Единственной информацией, предоставляемой методу, является свойство sequenceName
определенное в @SequenceGenerator
:
public class SchemaPostgreSQLDialect extends PostgreSQL82Dialect {
@Override
public String getSequenceNextValString(String sequenceName) {
String seqFinalName = mySequenceNameModifierMethod(sequenceName);
return "select nextval('" + seqFinalName + "')";
}
private String mySequenceNameModifierMethod(String originalSequenceName) {
// magic modification here
return modifiedSequenceName;
}
}
Я не использовал этот последний способ для изменения названия последовательностей, потому что он кажется менее подходящим для моего случая.
Ответ 9
Здравствуйте, у меня была такая же проблема.
но установите hibernate.hbm2ddl.auto для обновления и запуска.
<property name="hibernate.hbm2ddl.auto">update</property>