java - 使用 Spring Data 时,我应该如何注册自定义 Hibernate 5 数据类型(BasicType)?

标签 java spring hibernate spring-data hibernate-mapping

我使用 Spring Data 并决定创建可在 Hibernate 实体中使用的新自定义数据类型。我检查了文档并选择了 BasicType 并根据这个 official user guide 实现了它.

我希望能够在其类名下注册该类型,并能够在实体中使用新类型而不需要 @Type 注释。不幸的是,我无法获得对 MetadataBuilder 或 Hibernate 配置的引用以注册新类型。有没有办法在 Spring Data 中获取它?似乎 Hibernate 的初始化对用户是隐藏的,不能轻易访问。我们使用以下类来初始化 JPA:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory",
        transactionManagerRef = "transactionManager",
        basePackages = {
                "..." // omitted
        }
)
public class JpaConfiguration implements TransactionManagementConfigurer {

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory(
        DataSource dataSource,
        SchemaPerTenantConnectionProviderImpl provider) {

        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setPersistenceUnitName("defaultPersistenceUnit");
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setPackagesToScan(
                "..." // omitted
        );
        entityManagerFactoryBean.setJpaProperties(properties(provider));
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return entityManagerFactoryBean;
    }

    @Primary
    @Bean(name = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new JpaTransactionManager();
    }

    private Properties properties(SchemaPerTenantConnectionProviderImpl provider) {
        Properties properties = new Properties();
        // omitted
        return properties;
    }
}

我找到了很多关于如何使用 Hibernate 的配置对象来完成它的文章,但这篇文章是指 Hibernate 3 和 4。我还找到了如何通过 Hibernate org.hibernate.integrator.spi.Integrator 来完成它的方法 但是当我根据我发现的文章使用它时,我会收到异常信息 “org.hibernate.HibernateException: Can not alter TypeRegistry at this time” 在 Spring Data 中注册自定义类型的正确方法是什么?

最佳答案

我终于明白了。我会在这里发布给其他人:

我创建了一个实现 org.hibernate.boot.spi.SessionFactoryBuilderFactory 接口(interface)的新类。在此类中,我可以从元数据中获取对 TypeResolver 的引用并注册我的自定义类型。

package com.example.configuration;

import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryBuilderFactory;
import org.hibernate.boot.spi.SessionFactoryBuilderImplementor;
import org.slf4j.LoggerFactory;

import com.example.CustomType;

public class CustomDataTypesRegistration implements SessionFactoryBuilderFactory {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CustomDataTypesRegistration.class);

    @Override
    public SessionFactoryBuilder getSessionFactoryBuilder(final MetadataImplementor metadata, final SessionFactoryBuilderImplementor defaultBuilder) {
        logger.info("Registering custom Hibernate data types");
        metadata.getTypeResolver().registerTypeOverride(CustomType.INSTANCE);
        return defaultBuilder;
    }
}

然后必须通过 Java ServiceLoader mechanism 注册类(class)通过将类的全名及其包添加到名为 org.hibernate.boot.spi.SessionFactoryBuilderFactory 的文件中,并将其添加到 java 模块的 META-INF/services 目录中:

src/main/resources/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory

文件可以包含多行,每行引用不同的类。在这种情况下是:

com.example.configuration.CustomDataTypesRegistration 

这样 Spring Data 就会启动,自定义类型在 Hibernate 初始化期间成功注册。

对我帮助很大的是这个 SO answer在 Spring Data 下处理 Hibernate 5 中的模式导出。

关于java - 使用 Spring Data 时,我应该如何注册自定义 Hibernate 5 数据类型(BasicType)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42695339/

相关文章:

java - HHH000431 : Unable to determine H2 database version, 某些功能可能无法工作

hibernate - hibernate/grails-将字符串保存为long的异常

java - 在外部类中使用 findViewById

java - 匹配星号但不匹配星号

java - 从 Spring Boot 执行 Neo4j 密码查询

java - Kafka序列化-反序列化问题

java - 将数据库查找映射到 jpa 实体

java - CayenneModeler 未生成 Cayenne.xml

java - 从 jar 文件生成 jad 文件

java - 如何在java运行时创建新添加的类的实例