How is my id being generated with JPA using Hibernate with the Oracle 10g dialect?
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 databa开发者_运维百科se there a single sequence named 'hibernate_sequence' and no other hibernate 'special tables'.
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;
...
...
}
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;
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.
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
精彩评论