Issue
When using plain Hibernate this can be done in the following way:
public class MyLocalSessionFactoryBean extends LocalSessionFactoryBean {
// can also be made configurable e.g. with Springs EL...
private Class myIdentifierGeneratorClass = MyIdentifierGeneratorClass.class;
@Override
protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {
Configuration config = getConfiguration();
MutableIdentifierGeneratorFactory identifierGeneratorFactory = config.getIdentifierGeneratorFactory();
identifierGeneratorFactory.register("xyz", myIdentifierGeneratorClass);
return super.buildSessionFactory(sfb);
}
}
Now it's possible to write e.g.
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(generator = "generatorName")
@GenericGenerator(name = "generatorName", strategy = "xyz")
private Long id;
}
How can this be achieved when using Hibernate JPA EntityManager?
Maybe by utilising LocalContainerEntityManagerFactoryBean#postProcessEntityManagerFactory(EntityManagerFactory emf, PersistenceUnitInfo pui)
?
I've also found EntityManagerFactoryBuilderImpl#buildHibernateConfiguration(ServiceRegistry serviceRegistry)
but I don't know where to "hook in" (I'm using Spring and/or Spring-Boot and Spring-Data).
Thanks in advance!
Solution
You need to provide a hibernate.ejb.identifier_generator_strategy_provider
configuration property which defines the fully qualified name of your IdentifierGeneratorStrategyProvider
implementation.
This IdentifierGeneratorStrategyProvider
interface defines the following method:
public Map<String,Class<?>> getStrategies();
which you need to implement and define your own strategy there.
During bootstrap the EntityManager
will be configured like this:
final Object idGeneratorStrategyProviderSetting = configurationValues.remove( AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
if ( idGeneratorStrategyProviderSetting != null ) {
final IdentifierGeneratorStrategyProvider idGeneratorStrategyProvider =
strategySelector.resolveStrategy( IdentifierGeneratorStrategyProvider.class, idGeneratorStrategyProviderSetting );
final MutableIdentifierGeneratorFactory identifierGeneratorFactory = ssr.getService( MutableIdentifierGeneratorFactory.class );
if ( identifierGeneratorFactory == null ) {
throw persistenceException(
"Application requested custom identifier generator strategies, " +
"but the MutableIdentifierGeneratorFactory could not be found"
);
}
for ( Map.Entry<String,Class<?>> entry : idGeneratorStrategyProvider.getStrategies().entrySet() ) {
identifierGeneratorFactory.register( entry.getKey(), entry.getValue() );
}
}
so, the strategy you define will be configured in the MutableIdentifierGeneratorFactory
just as you were doing previously.
Answered By - Vlad Mihalcea
Answer Checked By - David Marino (JavaFixing Volunteer)