How should I register custom Hibernate 5 data type (BasicType) when Spring Data is used?(使用 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)?
基础教程推荐
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 降序排序:Java Map 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01