I am using Hibernate 3.3.2 with Oracle 10g.
On all my tables, I use an Oracle sequence to create my Primary Key.
To improve the performance, I have started using the pooled optimizer, because I wanted also to be able to use the sequence through SQL while my application is running.
To be consistent, I use the same increment size for the sequence and for the GenericGenerator.
My issue is the following:
I create new entries using my application.
Then I create new entries using SQL scripts with the sequence to generate the identifier.
If I create again new entries with my application, I then have an error message complaining that my primary key is duplicated.
I had a look at the optimizer and I found the source of my problem:
When the value is equal or bigger than the hiValue, then a new hiValue is computed using the sequence.
but the new value is computed as follow: value = hiValue - incrementSize and will go to the previous sequence value.
in my case as I have used the sequence 'manually', that value has already been allocated and the insertion fails.
I tend to think that the pooled here is buggy as far as it is supposed to let you play with SQL sequence manually, but I would like to have a confirmation.
On my side, I have found a simple workaround by using in the GenericGenerator, an increment size that is equals to the increment size of the Oracle sequence minus one.
My initial source code:
Code:
@Entity
@GenericGenerator(name="Generator.Recipient", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
@Parameter(name = "sequence_name", value = "SEQ_BCM_RECIPIENT"),
@Parameter(name = "increment_size", value = "20"),
@Parameter(name = "optimizer", value = "pooled")})
@Table(name = "BCM_RECIPIENT")
public class Recipient implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Generator.Recipient")
@Column(name = "REC_ID", insertable = false, updatable = false, nullable = false)
private Long id;
....
}
and my sequence :
Code:
CREATE SEQUENCE seq_bcm_recipient INCREMENT BY 20 START WITH 1 NOMAXVALUE MINVALUE 1 NOCYCLE CACHE 100 NOORDER;
the workaround, I made in my code:
Code:
@Entity
@GenericGenerator(name="Generator.Recipient", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
@Parameter(name = "sequence_name", value = "SEQ_BCM_RECIPIENT"),
@Parameter(name = "increment_size", value = "19"),
@Parameter(name = "optimizer", value = "pooled")})
@Table(name = "BCM_RECIPIENT")
public class Recipient implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Generator.Recipient")
@Column(name = "REC_ID", insertable = false, updatable = false, nullable = false)
private Long id;
....
}
Can someone confirm whether that behavior is expected or not?
Thanks for your help.