in google-cloud-spanner-hibernate-dialect/src/main/java/com/google/cloud/spanner/hibernate/BitReversedSequenceStyleGenerator.java [280:325]
public Object generate(SharedSessionContractImplementor session, Object object)
throws HibernateException {
Object id;
// Loop to skip excluded ranges.
while (true) {
int attempts = 0;
// Loop to retry the transaction that updates the table-backed sequence if it fails due to a
// concurrent modification error. This can happen if multiple entities are using the same
// sequence for generated primary keys.
while (true) {
try {
id = generateBaseValue(session, object);
break;
} catch (GenericJDBCException exception) {
JdbcAbortedDueToConcurrentModificationException aborted;
if (exception.getSQLException()
instanceof JdbcAbortedDueToConcurrentModificationException) {
aborted = (JdbcAbortedDueToConcurrentModificationException) exception.getSQLException();
} else {
throw exception;
}
attempts++;
if (attempts == MAX_ATTEMPTS) {
throw exception;
}
try {
sleep(aborted.getCause().getRetryDelayInMillis());
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw new IdentifierGenerationException(
"Interrupted while trying to generate a new ID", interruptedException);
}
}
}
if (id instanceof Long) {
Long reversed = Long.reverse((Long) id);
if (excludeRanges.stream().noneMatch(range -> range.contains(reversed))) {
return reversed;
}
log.debugf(
"Skipping reversed id %d (original id %d) as it is in an excluded range", reversed, id);
} else {
return id;
}
}
}