Параметр схемы 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>