8

I have some code:

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

How is hibernate providing my id?

I see in my database there a single sequence named 'hibernate_sequence' and no other hibernate 'special tables'.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
JavaRocky
  • 19,203
  • 31
  • 89
  • 110

4 Answers4

12

Actually, here your SOMETHING_SEQ is the name of sequence you configured somewhere in your hibernate config. And hibernate_sequence is the sequence name in the database. In configuration it would be looking something like below,

<sequence-generator name="SOMETHING_SEQ" 
    sequence-name="hibernate_sequence"
    allocation-size="<any_number_value>"/>

You can completely skip this configuration by using annotation instead. Then your @SequenceGenerator annotation would need to provide few more paramters. Below is the example.

@SequenceGenerator(name="SOMETHING_SEQ", sequenceName="hibernate_sequence", allocationSize=10)

For example multiple entity classes would do something like below,

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

  ...
  ...

}
Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
  • Thanks. But in my case, how is hibernate providing my id? As when i save my entity with a null value for my Long id, it magically is auto inserted. Is it via some special table, or using that hibernate_sequence? Or..? – JavaRocky Mar 05 '10 at 04:58
  • Using the `hibernate-seq`, and of course when you said Hibernate to generate it, you must not provide any yourself. Or even if you provide some value per say, that value would get overwritten. – Adeel Ansari Mar 05 '10 at 07:30
  • Are you saying multiple entities share this same hibernate sequence? – JavaRocky Mar 05 '10 at 22:42
  • Not necessarily. You can define otherwise, check my addemdum. If you defined just one sequence for every entity, then yes it will use the same sequence. – Adeel Ansari Mar 06 '10 at 04:06
5

How is hibernate providing my id?

Well, you explicitly told the JPA engine to generate identifier automatically (with the @GeneratedValue annotation) using a strategy of type SEQUENCE indicating that a database sequence should be used to generate the identifier. In case you wonder, sequences are database specific objects (e.g. Oracle) that can be used to generate unique integers.

I see in my database there a single sequence named 'hibernate_sequence'

You didn't use the sequenceName annotation element in your @SequenceGenerator to specify the name of the database sequence object to use so Hibernate created a default sequence object during schema generation (which defaults to hibernate_sequence). To specify a sequence, do it like this:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_seq_gen")
@SequenceGenerator(name = "my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private Long id;
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
4

In order to name the sequence you have to set the sequenceName in your @SequenceGenerator annotation:

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

Of note, if you are using a pre-existing generator, your allocationSize must match the allocation size of that generator.

RubioRic
  • 2,442
  • 4
  • 28
  • 35
kgrad
  • 4,672
  • 7
  • 36
  • 57
0

In Oracle you don't have the auto_increment type as in MySQL. So, to generate an auto_increment column you need to use a sequence.

This is an example of how you can achieve this.

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;

So you create a sequence and use a trigger before each row is inserted to add its id.

So hibernate must be doing something like this, or instead of using the trigger doing

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

Note: Example taken from here

Lombo
  • 11,847
  • 2
  • 20
  • 27
  • Thank-you. Indeed Oracle does not have the auto_increment capability. However, when i save my @Entity's i leave my @Id fields null. Which then the EntityManager somehow generates an id from somewhere and inserts it. I know this when i enable the SQL output to the console. So coming back to my question, from where does this id come from with my configuration? – JavaRocky Mar 05 '10 at 05:00
  • it uses the sequence for sure. Now if it uses the trigger, or the inline insert, configure hibernate to show sql or check if a trigger was generated – Lombo Mar 05 '10 at 09:29
  • Hibernate doesn't use a trigger, it just gets the `nextval` on insert. – Pascal Thivent Mar 05 '10 at 15:21