如何在 Hibernate JPA EntityManager 中注册自定义 IdentifierGenerator?
How to register custom IdentifierGenerator in Hibernate JPA EntityManager?
当使用普通 Hibernate 时,可以通过以下方式完成:
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);
}
}
现在可以这样写了
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(generator = "generatorName")
@GenericGenerator(name = "generatorName", strategy = "xyz")
private Long id;
}
使用 Hibernate JPA EntityManager 时如何实现?
也许利用 LocalContainerEntityManagerFactoryBean#postProcessEntityManagerFactory(EntityManagerFactory emf, PersistenceUnitInfo pui)
?
我也找到了 EntityManagerFactoryBuilderImpl#buildHibernateConfiguration(ServiceRegistry serviceRegistry)
但我不知道 "hook in" 在哪里(我正在使用 Spring and/or Spring-Boot和 Spring-数据)。
提前致谢!
您需要提供一个 hibernate.ejb.identifier_generator_strategy_provider
配置 属性,它定义了您的 IdentifierGeneratorStrategyProvider
实现的完全限定名称。
这个IdentifierGeneratorStrategyProvider
接口定义了以下方法:
public Map<String,Class<?>> getStrategies();
您需要在那里实施和定义自己的策略。
在 bootstrap 期间,EntityManager
将配置如下:
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() );
}
}
因此,您定义的策略将在 MutableIdentifierGeneratorFactory
中配置,就像您之前所做的那样。
当使用普通 Hibernate 时,可以通过以下方式完成:
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);
}
}
现在可以这样写了
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(generator = "generatorName")
@GenericGenerator(name = "generatorName", strategy = "xyz")
private Long id;
}
使用 Hibernate JPA EntityManager 时如何实现?
也许利用 LocalContainerEntityManagerFactoryBean#postProcessEntityManagerFactory(EntityManagerFactory emf, PersistenceUnitInfo pui)
?
我也找到了 EntityManagerFactoryBuilderImpl#buildHibernateConfiguration(ServiceRegistry serviceRegistry)
但我不知道 "hook in" 在哪里(我正在使用 Spring and/or Spring-Boot和 Spring-数据)。
提前致谢!
您需要提供一个 hibernate.ejb.identifier_generator_strategy_provider
配置 属性,它定义了您的 IdentifierGeneratorStrategyProvider
实现的完全限定名称。
这个IdentifierGeneratorStrategyProvider
接口定义了以下方法:
public Map<String,Class<?>> getStrategies();
您需要在那里实施和定义自己的策略。
在 bootstrap 期间,EntityManager
将配置如下:
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() );
}
}
因此,您定义的策略将在 MutableIdentifierGeneratorFactory
中配置,就像您之前所做的那样。