I have legacy Oracle db with a sequence named PRODUCT_ID_SEQ
.
Here is the mapping of Product
class for which I need generate correct ids:<
Here is a working example with annotations, this way, the existing DB sequence will be used (you can also use the "sequence" strategy, but with less performance on insertion) :
@Entity
@Table(name = "USER")
public class User {
// (...)
@GenericGenerator(name = "generator", strategy = "sequence-identity", parameters = @Parameter(name = "sequence", value = "USER_SEQ"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
public Long getId() {
return this.id;
}
If you use javax.persistence.SequenceGenerator, hibernate use hilo and will possibly create large gaps in the sequence. There is a post addressing this problem: https://forum.hibernate.org/viewtopic.php?t=973682
there are two ways to fix this problem
In the SequenceGenerator annotation, add allocationSize = 1, initialValue= 1
instead of using javax.persistence.SequenceGenerator, use org.hibernate.annotations, like this:
@javax.persistence.SequenceGenerator(name = "Question_id_sequence", sequenceName = "S_QUESTION")
@org.hibernate.annotations.GenericGenerator(name="Question_id_sequence", strategy = "sequence", parameters = { @Parameter(name="sequence", value="S_QUESTION") } )
I have tested both ways, which works just fine.
By default Hibernate uses sequence HiLo generator which ,unless you have special needs, it is good (performance wise). You can read more of that in my blog here
Eyal
First : you should create in your database the sequence like:
CREATE SEQUENCE "PRODUCT_ID_SEQ" MINVALUE 0 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1 CACHE 500 NOORDER NOCYCLE ;
and in your file Product.hbm.xml configuration make :
<class name="ProductPersistant" table="Product">
<id name="id" type="java.lang.Long" column="productID" >
<generator class="sequence">
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
</id>
Create your sequence name in Oracle, for example, contacts_seq. In Your POJO Class . Define the following annotation for your sequence.
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
allocationSize and incrementBy are completely different things.
Hibernate is of course using your sequence created in DB but depending on allocationSize you might find gap in generated value.
For example- Let assume current sequence value is 5, increment by 1 in db, and allocationSize default 50.
Now you want to save a collection of 3 element through hibernate, then Hibernate will assign generated id 250, 251, 252
This is for optimization purpose. Hibernate doesn't have to go back to db and fetch next incremented value.
If you don't want this just setting allocationSize = 1
as already answered will do the purpose