Как мой идентификатор генерируется с помощью JPA с использованием Hibernate с диалектом Oracle 10g? - PullRequest
7 голосов
/ 05 марта 2010

У меня есть код:

@Id
@SequenceGenerator(name = "SOMETHING_SEQ")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOMETHING_SEQ")
@Column(name = "SOMETHING", nullable = false)
private Long id;

Как hibernate предоставляет мой идентификатор?

Я вижу в своей базе данных одну последовательность с именем 'hibernate_sequence' и никаких других hibernate 'специальных таблиц'.

Ответы [ 4 ]

10 голосов
/ 05 марта 2010

На самом деле, здесь ваш SOMETHING_SEQ - это имя последовательности, которую вы сконфигурировали где-то в вашей конфигурации hibernate. И 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;

  ...
  ...

}
4 голосов
/ 06 марта 2010

Как hibernate предоставляет мой идентификатор?

Ну, вы явно указали движку 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;
4 голосов
/ 05 марта 2010

Чтобы назвать последовательность, вы должны установить sequenceName в аннотации @SequenceGenerator:

@GeneratedValue(name="gen", strategy = GeneratorType.SEQUENCE)
@SequenceGenerator(name="gen", sequenceName="Sequence_Name", allocationSize = 1)
@Id
public Long getId()
{
    // ...
}

Следует отметить, что если вы используете уже существующий генератор, ваш allocationSize должен соответствовать размеру выделения этого генератора.

0 голосов
/ 05 марта 2010

В 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;

Таким образом, вы создаете последовательность и используете триггер перед каждой строкой, чтобы добавить свой идентификатор.

Так что hibernate должен делать что-то вроде этого, или вместо использования триггера, делая

insert into test values(test_seq.nextval, 'no trigger needed!');

Примечание: пример взят из здесь

...