I have an entity with @GeneratedValue and @SequenceGenerator with strategy SEQUENCE which is used in different applications and a physical naming strategy that replaces a part of te name from the sequence. The sequenceMismatchStrategy in SequenceStyleGenerator is getting skipped because it uses the wrong name to get the sequence from the database.
This can cause problems because the alllocationSize in the Entity and increment value from the database can now differ without getting noticed.
Entity:
@Id
@GeneratedValue(generator = "REPLACE_MY_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "REPLACE_MY_SEQ", sequenceName = "REPLACE_MY_SEQ")
protected Long id;
The PhysicalNamingStrategy replaces ‘REPLACE’ with an applicationcode:
public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
return Identifier.toIdentifier(identifier.getText().replaceAll("^REPLACE_", this.applicationcode + "_"), identifier.isQuoted());
}
When the SequenceStyleGenerator gets configured for a pooled optimizer it will use REPLACE_MY_SEQ to get the sequence from the database. This doesn’t exists because the physical name is AB_MY_SEQ and the sequenceMismatchStrategy is skipped
if ( sequenceMismatchStrategy != SequenceMismatchStrategy.NONE && isPooledOptimizer && isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
//this is REPLACE_MY_SEQ instead of AB_MY_SEQ
String databaseSequenceName = sequenceName.getObjectName().getText();
//this is null because the sequence doesn't exist
Long databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
// this is getting skipped because databaseIncrementValue is null
if ( databaseIncrementValue != null && !databaseIncrementValue.equals( (long) incrementSize ) ) {
int dbIncrementValue = databaseIncrementValue.intValue();
switch ( sequenceMismatchStrategy ) {
case EXCEPTION:
throw new MappingException(
String.format(
"The increment size of the [%s] sequence is set to [%d] in the entity mapping " +
"while the associated database sequence increment size is [%d].",
databaseSequenceName, incrementSize, dbIncrementValue
)
);
case FIX:
incrementSize = dbIncrementValue;
case LOG:
LOG.sequenceIncrementSizeMismatch( databaseSequenceName, incrementSize, dbIncrementValue );
break;
}
}
After configuring the SequenceGenerator the PhysicalNamingStrategy gets configured. When persisting an Entity to the database it will use the correct name to get the id
//this uses the correct name to get an id from the sequence
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
return optimizer.generate( databaseStructure.buildCallback( session ) );
}
I think the SequenceStyleGenerator should respect the physical naming strategy when it configures itself