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

查看:377
本文介绍了使用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:暂时无法更改TypeRegistry" 的异常. 在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数据,并在Hibernate初始化期间成功注册自定义类型.

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

SO答案处理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)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆