I managed to take the existing NoopOptimzer and write a new class that always returns false for applyIncrementSizeToSourceValues
method, and that works!
Hibernate: select nextval ('userentity_seq')
Added user user000000 with ID: 101543
Hibernate: insert into userentity (username, user_id) values (?, ?)
Hibernate: select nextval ('userentity_seq')
Added user user000001 with ID: 101563
Hibernate: insert into userentity (username, user_id) values (?, ?)
Hibernate: select nextval ('userentity_seq')
Added user user000002 with ID: 101583
Hibernate: insert into userentity (username, user_id) values (?, ?)
Will I have to do this in Hibernate 6 as well? Personally, I think this validation requiring the allocationSize to be the same as the Increment By is overzealous, especially when using the NoopOptimizer.
I would have extended the NoopOptimizer class, but it is marked final.
Here is the modified class, with applyIncrementSizeToSourceValues set to always return false:
package org.hibernate.id.enhanced;
import java.io.Serializable;
import org.hibernate.id.IntegralDataTypeHolder;
public class DbSequenceOptimizer extends AbstractOptimizer{
private IntegralDataTypeHolder lastSourceValue;
DbSequenceOptimizer(Class returnClass, int incrementSize)
{
super(returnClass, incrementSize);
}
@Override
public Serializable generate(AccessCallback callback) {
// IMPL NOTE : this method is called concurrently and is
// not synchronized. It is very important to work on the
// local variable: the field lastSourceValue is not
// reliable as it might be mutated by multiple threads.
// The lastSourceValue field is only accessed by tests,
// so this is not a concern.
IntegralDataTypeHolder value = callback.getNextValue();
lastSourceValue = value;
return value.makeValue();
}
@Override
public IntegralDataTypeHolder getLastSourceValue() {
return lastSourceValue;
}
@Override
public boolean applyIncrementSizeToSourceValues() {
// We allow the increment size to be 0 for backward-compatibility with legacy
// ID generators; we don't apply a value of 0, so the default will be used instead.
// We don't apply an increment size of 1, since it is already the default.
// return getIncrementSize() != 0 && getIncrementSize() != 1;
return false;
}
}