У меня есть некоторый код:
@Id
@SequenceGenerator(name = "SOMETHING_SEQ")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOMETHING_SEQ")
@Column(name = "SOMETHING", nullable = false)
private Long id;
Как, в спящем режиме, предоставляя мой идентификатор?
Я вижу в своей базе данных там единственную последовательность, названную 'hibernate_sequence', и никто другой не в спящем режиме 'специальные таблицы'.
Фактически, здесь ваш SOMETHING_SEQ
- это имя последовательности, которую вы настроили где-то в конфигурации гибернации. А hibernate_sequence
- это имя последовательности в базе данных. В конфигурации это будет выглядеть примерно так, как показано ниже:
<sequence-generator name="SOMETHING_SEQ"
sequence-name="hibernate_sequence"
allocation-size="<any_number_value>"/>
Вы можете полностью пропустить эту конфигурацию, используя вместо нее аннотацию. Тогда ваша аннотация @SequenceGenerator
должна будет содержать еще несколько параметров. Ниже приведен пример.
@SequenceGenerator(name="SOMETHING_SEQ", sequenceName="hibernate_sequence", allocationSize=10)
Например, несколько классов сущностей будут делать что-то вроде ниже:
@Entity
public class Entity1 {
@Id
@SequenceGenerator(name = "entity1Seq", sequenceName="ENTITY1_SEQ", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity1Seq")
@Column(name = "ID", nullable = false)
private Long id;
...
...
}
@Entity
public class Entity2 {
@Id
@SequenceGenerator(name = "entity2Seq", sequenceName="ENTITY2_SEQ", allocationSize=10)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity2Seq")
@Column(name = "ID", nullable = false)
private Long id;
...
...
}
Чтобы назвать последовательность, вы должны установить имя_последовательности
] в аннотации @SequenceGenerator
:
@GeneratedValue(name="gen", strategy = GeneratorType.SEQUENCE)
@SequenceGenerator(name="gen", sequenceName="Sequence_Name", allocationSize = 1)
@Id
public Long getId()
{
// ...
}
Следует отметить, что если вы используете уже существующий генератор, ваш allocationSize
должен соответствовать размеру выделения этого генератора.
Как спящий режим предоставляет мой идентификатор?
Итак, вы явно указали механизму JPA автоматическое создание идентификатора (с аннотацией @GeneratedValue
) с использованием стратегии типа SEQUENCE
, указывающей, что последовательность базы данных ] следует использовать для генерации идентификатора. Если вам интересно, последовательности - это объекты базы данных (например, Oracle), которые можно использовать для генерации уникальных целых чисел.
Я вижу в своей базе данных единственную последовательность с именем 'hibernate_sequence'
Вы не использовали элемент аннотации sequenceName
в своем @SequenceGenerator
, чтобы указать имя объект последовательности базы данных для использования, чтобы Hibernate создал объект последовательности по умолчанию во время генерации схемы (который по умолчанию равен hibernate_sequence
). Чтобы указать последовательность, сделайте это так:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_seq_gen")
@SequenceGenerator(name = "my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private Long id;
В Oracle у вас нет типа auto_increment, как в MySQL. Поэтому для создания столбца auto_increment необходимо использовать последовательность.
Вот пример того, как этого можно добиться.
create table test (id number, testdata varchar2(255));
create sequence test_seq
start with 1
increment by 1
nomaxvalue;
create trigger test_trigger
before insert on test
for each row
begin
select test_seq.nextval into :new.id from dual;
end;
Итак, вы создаете последовательность и используете триггер перед вставкой каждой строки для добавления ее id.
Поэтому hibernate должен делать что-то подобное, или вместо использования триггера делать
insert into test values(test_seq.nextval, 'no trigger needed!');
Примечание: Пример взят из здесь