Friday, February 26, 2010

Hibernate Annotation and MultipleHiloPerTableGenerator

This is the example of how to define hilo generator by using annotation that I found in Hibernate Annotation document.


@Id @GeneratedValue(generator="hibseq")
@GenericGenerator(name="hibseq", strategy = "seqhilo",
    parameters = {
        @Parameter(name="max_lo", value = "5"),
        @Parameter(name="sequence", value="heybabyhey")
    }
)
public Integer getId() {
 

But when I apply to MultipleHiloPerTableGenerator, I always get exception. The way I do is like below.


@Id @GeneratedValue(generator="hibseq")
@GenericGenerator(name="hibseq", strategy = "org.hibernate.id.MultipleHiloPerTableGenerator",
    parameters = {
        @Parameter(name="max_lo", value = "100"),
    }
)
public Integer getId() {

Since no short name for MultipleHiloPerTableGenerator, I have to put the full class name into strategy according to documentation. The reason we use this generator is based on following reasons.We often have huge amount of insertion jobs, like inserting 1M records in one operation. If we use auto-increment primary key, what Hibernate does is issue a database access to get the id when you call save(object) method, then 1M insert statement will generate 2M database access, which extremely slows down the process.  MultipleHiloPerTableGenerator use a table(default name is hibernate_sequences) to save a hi value for each entity that use this generator. It uses a separate session to retrieve the hi value, at the same time update the hi value to current hi + max_lo, when the save(object) is called, it assigned the id as hi plus sequence number, the max value of sequence number is defined by property max_lo. If the sequence number reaches to the max, the generator will retrieve another hi value. In a short explanation, each session gets pre-assign a chunk of id pool. So, this generator can reduce the time consumption on retrieving id. When the insertion is huge, it saves a great deal of time.

The correct way is to add strategy attribute for @GeneratedValue. To modify the annotation like this.


@Id @GeneratedValue(generator="hibseq", strategy=GenerationType.TABLE)
@GenericGenerator(name="hibseq", strategy = "org.hibernate.id.MultipleHiloPerTableGenerator",
    parameters = {
        @Parameter(name="max_lo", value = "100"),
    }
)
public Integer getId() {


Easy, but I spent a whole afternoon tracing the Hibernate source code to find that out.

1 comment:

thr27 said...

I had an error with the classname in your sample. It is "org.hibernate.id.MultipleHiLoPerTableGenerator" not "org.hibernate.id.MultipleHiloPerTableGenerator" (lo => Lo)

Google+