Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

java - Hibernate, @SequenceGenerator and allocationSize

We all know the default behaviour of Hibernate when using @SequenceGenerator - it increases real database sequence by one, multiple this value by 50 (default allocationSize value) - and then uses this value as entity ID.

This is incorrect behaviour and conflicts with specification which says:

allocationSize - (Optional) The amount to increment by when allocating sequence numbers from the sequence.

To be clear: I do not bother about gaps between generated IDs.

I care about IDs that are not consistent with underlying database sequence. For example: any other application (that e.g. uses plain JDBC) may want to insert new rows under IDs obtained from sequence - but all those values may be already used by Hibernate! Madness.

Do somebody know any solution to this problem (without setting allocationSize=1 and thus degrading performance)?

EDIT:
To make things clear. If last inserted record had ID = 1, then HB use values 51, 52, 53... for its new entities BUT at the same time: sequence's value in database will be set to 2. Which can easily leads to errors when other applications are using that sequence.

On the othe hand: specification says (in my understanding) that database sequence should have been set to 51 and in the meantime HB should use values from range 2, 3 ... 50


UPDATE:
As Steve Ebersole mentioned below: the behaviour described by me (and also the most intuitive for many) can be enabled by setting hibernate.id.new_generator_mappings=true.

Thanks all of You.

UPDATE 2:
For future readers, below you can find a working example.

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
    @SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
    private Long id;
}

persistence.xml

<persistence-unit name="testPU">
  <properties>
    <property name="hibernate.id.new_generator_mappings" value="true" />
  </properties>
</persistence-unit>
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To be absolutely clear... what you describe does not conflict with the spec in any way. The spec talks about the values Hibernate assigns to your entities, not the values actually stored in the database sequence.

However, there is the option to get the behavior you are looking for. First see my reply on Is there a way to dynamically choose a @GeneratedValue strategy using JPA annotations and Hibernate? That will give you the basics. As long as you are set up to use that SequenceStyleGenerator, Hibernate will interpret allocationSize using the "pooled optimizer" in the SequenceStyleGenerator. The "pooled optimizer" is for use with databases that allow an "increment" option on the creation of sequences (not all databases that support sequences support an increment). Anyway, read up about the various optimizer strategies there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...