I am using hibernate 3 , oracle 10g. I have a table: subject. The definition is here
CREATE TABLE SUBJECT
(
SUBJECT_ID NUMBER (10),
FNAME VARCHAR2(30) not null,
LNAME VARCHAR2(30) not null,
EMAILADR VARCHAR2 (40),
BIRTHDT DATE not null,
constraint pk_sub primary key(subject_id) USING INDEX TABLESPACE data_index
)
;
when insert a new subject, sub_seq is used to create an subject id, the definition is here
create sequence sub_seq
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 100
NOCYCLE ;
the Subject class is like this:
@Entity
@Table(name="ktbs.syn_subject")
public class Subject {
@Id
@Column(name="subject_id")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SUB_SEQ")
@SequenceGenerator(name="SUB_SEQ", sequenceName = "SUB_SEQ")
private long subjectId;
private String fname;
private String lname;
private String emailadr;
private Date birthdt;
}
in the subject table , there have been 4555 subjects in the database loaded by plsql scripts from excel and the sub_sequence worked fine. subject ids range from 1--4555.
however, when i added a subject from my application using hibernate, the sequence number jumped to 255050. After several days running, the subject ids generated by hibernate look like this
270079
270078
270077
270076
270075
270074
270073
270072
270071
270070
270069
270068
270067
270066
270065
270064
270063
270062
270061
270060
270059
270058
270057
270056
270055
270054
270053
270052
270051
270050
265057
265056
265055
265054
265053
265052
265051
265050
260059
260058
260057
260056
260055
260054
260053
260052
260051
260050
255067
255066
255065
255064
255063
255062
255061
255060
255059
255058
255057
255056
255055
255054
255053
255052
255051
255050
4555
4554
4553
.
.
.
.
1
There are several large gaps: 4555 to 255051, 255067 to 260051, 265057 to 270051
this is a waste and not a desired behavior.
does anyone know why this happens and hot to fix it
Thanks
As said here, try to adjust your
SequenceGenerator.allocationSize
with your database sequenceINCREMENT BY
number.I had similar issues. sequence generator and sequence hilo generator are quite similar but have differences. In hibernate 3, hilo generator multiplies with default value 50. Therefore no need to increment DB sequence. On the other hand, later versions of hibernate uses sequence generator by default. Therefore DB increment by 50 is required.
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.3/html/Migration_Guide/Preserve_the_Existing_Behavior_of_the_Hibernate_Identity_Auto_Generated_Value1.html
I had this issue which have multiple hibernate versions (3 and 5). Same configuration worked fine (incremented by 1 in DB). But failed in hibernate 5. Therefore I update my persistence.xml as below. This ensures hilo generation
Actually having allocationSize=1 is fine if your sequence
INCREMENT VALUE
is 1 and you do not have the need of persisting a lot of entities. However if you want to persist thousands or millions of records, the above setting could become a performance bottleneck since every save need to fetch a id hence need a db read.To Solve this problem, we need to set the
allocationSize
to something like 500 and sequenceINCREMENT VALUE
in DB also to 500, then most important add a hibernate settinghibernate.id.new_generator_mappings
to ask it to use the new sequence generator implementation, here i assume you set your hibernate properties in a java Config class:This way, Hibernate will use
SequenceStyleGenerator
rather than the oldSequenceHiLoGenerator
to generate the ids. TheSequenceStyleGenerator
is more jpa and oracle friendly. It generates identifier values based on an sequence-style database structure. Variations range from actually using a sequence to using a table to mimic a sequence.Look at my post for more detail if you are in the same boat:
vcfvct.wordpress.com/2016/04/23/jpa-sequencegenerator-with-allocationsize-1-performance-tuning/