If a sequence generator is used in an entity, who references a sequence in a table, which generates negative IDs the application will stuck in an infinite loop.
Problem analysis:
org.hibernate.id.enhanced.NoopOptimizer.generate
Uses a while loop to get values from a sequence:
{{while ((value == null) || (value.lt(1L))) {
value = callback.getNextValue();
}}}
...
return value.makeValue();
If sequence generates negative ids, the condition will always be satisfied, what will end in an infinite loop.
On Hibernate ORM 3.3 the sequence generation worked with negative seqences.
Some test code:
CREATE SEQUENCE SQ_NEGATIVE MINVALUE -99999999999999999999999999 MAXVALUE -1 INCREMENT BY -1 START WITH -51976995 CACHE 20 NOORDER NOCYCLE;
{{@Entity
public class LoopEntity {
@Id
@GeneratedValue(generator = "objId", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "objId", sequenceName = "sq_negative", allocationSize = 1)
@Column(name = "ID", unique = true, nullable = false, insertable = true, updatable = true, precision = 22, scale = 0)
private Long id;
}}}
Hibernate ORM 5.0.0 Final
WebSphere Liberty Profile Application Server 8.5.5.7
Java HotSpot(TM) 64-Bit 1.8.0_45-b15
Oracle Database 11g 11.2.0.4.0
<property name="hibernate.id.new_generator_mappings" value="false" />
and
<property name="hibernate.id.new_generator_mappings" value="true" />
ended in similar loop.
Workaround:
@Id
@GenericGenerator(name = "neg_objId",
strategy = "org.hibernate.id.SequenceGenerator",
parameters = { @Parameter(name = "sequence", value = "sq_negative") }
)
@GeneratedValue(generator = "neg_objId")
@Column(name = "ID", unique = true, nullable = false, insertable = true, updatable = true, precision = 22, scale = 0)
private Long id;
I fixed this for the NoopOptimizer, but realized that the other optimizers all disallow negative generation. Maybe a future feature enhancement to allow that?
Thx for the fast fixing!
For us it is enough, if NoopOptimizer supports negative IDs.
It was a little suprising, that the application stucked in a loop. We could not find any documentation, that negative IDs are not supported anymore.
How about a additional entry in javadoc/user guide?
Well the optimizers are all new. Previously you had been using the id-gen strategies that did not support the Optimizer concept. So its not something that went away per-se. Its just that the Optimizer impls were developed without negative generation in mind : it's (more than) a bit unusual