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

How should I register custom Hibernate 5 data type (BasicType) when Spring Data is used?(使用 Spring Data 时应该如何注册自定义 Hibernate 5 数据类型(BasicType)?)

本文介绍了使用 Spring Data 时应该如何注册自定义 Hibernate 5 数据类型(BasicType)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Spring Data 并决定创建可在 Hibernate 实体中使用的新自定义数据类型.我检查了文档并选择 BasicType 并根据此 官方用户指南.

I use Spring Data and decided that I want to create new custom data type that can be used in Hibernate entities. I checked the documentation and choose BasicType and implemented it according to this official user guide.

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

I wanted to be able to register the type under its class name and be able to use the new type in entities without need for @Type annotation. Unfortunately, I’m unable to get reference to the MetadataBuilder or Hibernate configuration to register the new type. Is there a way how to get it in Spring Data? It seems that initialization of the Hibernate is hidden from the user and cannot be easily accessed. We use following class to initialize the 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 的 Configuration 对象的文章,但这篇文章指的是 Hibernate 3 和 4.我还找到了如何通过 Hibernate org.hibernate.integrator.spi.Integrator 进行操作的方法 但是当我根据我发现的文章使用它时,我会收到异常消息org.hibernate.HibernateException: Can not alter TypeRegistry at this time"在 Spring Data 中注册自定义类型的正确方法是什么?

I found lots of articles about way how to do it with Hibernate’s Configuration object but this one refers to Hibernate 3 and 4. I also found way how to do it via Hibernate org.hibernate.integrator.spi.Integrator but when I use it according to the articles I found I will get exception with the message "org.hibernate.HibernateException: Can not alter TypeRegistry at this time" What is the correct way to register custom types in Spring Data?

推荐答案

我终于想通了.我会在这里发布给其他人:

I finally figured it out. I will post it here for others:

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

I created a new class that implements org.hibernate.boot.spi.SessionFactoryBuilderFactory interface. In this class I can get reference to the TypeResolver from metadata and register my custom type.

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 机制注册该类 将类的全名及其包添加到名为 org.hibernate.boot.spi.SessionFactoryBuilderFactory 的文件中,并将其添加到 java 模块的 META-INF/services 目录:

The class must be then registered via Java ServiceLoader mechanism by adding full name of the class with its packages into the file with name org.hibernate.boot.spi.SessionFactoryBuilderFactory into the java module’s META-INF/services directory:

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

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

The file can contain multiple lines, each referencing different class. In this case it is:

com.example.configuration.CustomDataTypesRegistration 

这样 Spring Data 启动并且自定义类型在 Hibernate 初始化期间成功注册.

This way the Spring Data starts and custom type is successfully registered during Hibernate initialization.

对我帮助很大的是这个所以回答 在 Spring Data 下处理 Hibernate 5 中的模式导出.

What helped my quite a lot was this SO answer that deals with schema export in Hibernate 5 under Spring Data.

这篇关于使用 Spring Data 时应该如何注册自定义 Hibernate 5 数据类型(BasicType)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:使用 Spring Data 时应该如何注册自定义 Hibernate 5 数据类型(BasicType)?

基础教程推荐