如何使用 JPA EntityManager 注册自定义 Hibernate IdentifierGenerator?

bgr*_*ves 2 hibernate jpa sessionfactory entitymanager spring-data

当使用普通 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以写例如

@MappedSuperclass
public class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(generator = "generatorName")
    @GenericGenerator(name = "generatorName", strategy = "xyz")
    private Long id;
}
Run Code Online (Sandbox Code Playgroud)

使用 Hibernate JPA EntityManager 时如何实现这一点?

也许通过利用LocalContainerEntityManagerFactoryBean#postProcessEntityManagerFactory(EntityManagerFactory emf, PersistenceUnitInfo pui)

我也发现了EntityManagerFactoryBuilderImpl#buildHibernateConfiguration(ServiceRegistry serviceRegistry),但我不知道在哪里“挂钩”(我正在使用 Spring 和/或 Spring-Boot 和 Spring-Data)。

提前致谢!

Vla*_*cea 5

您需要提供一个hibernate.ejb.identifier_generator_strategy_provider配置属性来定义您的实现的完全限定名称IdentifierGeneratorStrategyProvider

IdentifierGeneratorStrategyProvider接口定义了以下方法:

public Map<String,Class<?>> getStrategies();
Run Code Online (Sandbox Code Playgroud)

您需要在那里实施并定义自己的策略。

在引导期间,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() );
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,您定义的策略将按照MutableIdentifierGeneratorFactory您之前所做的那样进行配置。