The problem still occurs in 4.3.5 version of Hibernate.
If two or more instances of application using HiLo generator access same instance of the databasse, then different instances generate duplicate identity values.
Steps to reproduce issue:
1) Create simple table with integer primary key column 2) Define JPA mapping of the table with SequenceStyleGenerator that uses HiLo generator
@Id @GenericGenerator(name = "sampleGenerator", strategy = "sequence" , parameters = { @Parameter(name = "optimizer", value = "hilo"), @Parameter(name = "initial_value", value = "1"), @Parameter(name = "increment_size", value = "100") }
) @GeneratedValue(strategy = GenerationType.TABLE, generator = "sampleGenerator") private Long id;
3) Create the test that inserts multiple rows (more than increment_size value) to the table 4) Run two instances (processes) of the test case on single database 5) Two tests instances will generate duplicate identifiers that will result in unique key constraint violation
Below is the fix of the problem.
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/HiLoOptimizer.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/HiLoOptimizer.java index d0ca9fd..dccd047 100644 — a/hibernate-core/src/main/java/org/hibernate/id/enhanced/HiLoOptimizer.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/HiLoOptimizer.java @@ -112,6 +112,7 @@ else if ( ! generationState.upperLimit.gt( generationState.value ) ) { generationState.lastSourceValue = callback.getNextValue(); generationState.upperLimit = generationState.lastSourceValue.copy().multiplyBy( incrementSize ).increment(); + generationState.value = generationState.upperLimit.copy().subtract( incrementSize ); }
return generationState.value.makeValueThenIncrement(); }
|