xMo*_*ort 9 java spring hibernate hibernate-mapping spring-data
我使用Spring Data并决定创建可以在Hibernate实体中使用的新自定义数据类型.我检查了文档,BasicType并根据此官方用户指南选择并实施它.
我希望能够在其类名下注册该类型,并且能够在实体中使用新类型而无需@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;
}
}
Run Code Online (Sandbox Code Playgroud)
我发现很多关于如何使用Hibernate的Configuration对象的文章,但是这个引用了Hibernate 3和4.我也找到了如何通过Hibernate来做到这一点org.hibernate.integrator.spi.Integrator但是当我根据我发现的文章使用它时我会得到异常消息"org.hibernate.HibernateException:此时无法更改TypeRegistry"
在Spring Data中注册自定义类型的正确方法是什么?
xMo*_*ort 12
我终于弄明白了.我会在这里发布给其他人:
我创建了一个实现org.hibernate.boot.spi.SessionFactoryBuilderFactory接口的新类.在这个类中,我可以引用TypeResolverfrom元数据并注册我的自定义类型.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后必须通过Java ServiceLoader机制注册该类,方法是将带有包的类的全名添加到名为org.hibernate.boot.spi.SessionFactoryBuilderFactoryjava模块META-INF/services目录的文件中:
src/main/resources/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory
Run Code Online (Sandbox Code Playgroud)
该文件可以包含多行,每行引用不同的类.在这种情况下,它是:
com.example.configuration.CustomDataTypesRegistration
Run Code Online (Sandbox Code Playgroud)
这样,Spring数据启动并在Hibernate初始化期间成功注册了自定义类型.
在Spring Data下,Hibernate 5中的模式导出处理了这个SO答案,这对我的帮助很大.
小智 8
xMort 所做的替代方法是通过 ServiceLoader 机制注册 org.hibernate.boot.model.TypeContributor。
\n\npackage com.example.configuration;\n\nimport org.hibernate.boot.model.TypeContributions;\nimport org.hibernate.boot.model.TypeContributor;\nimport org.hibernate.service.ServiceRegistry;\n\npublic class CustomTypeContributor implements TypeContributor {\n @Override\n public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {\n typeContributions.contributeType(CustomType.INSTANCE);\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n\nsrc/main/resources/META-INF/services/org.hibernate.boot.model.TypeContributor\nRun Code Online (Sandbox Code Playgroud)\n\nru.eastbanctech.scs.air.transaction.repositories.StringArrayTypeContributor\nRun Code Online (Sandbox Code Playgroud)\n\n从 Hibernate 5.2.17 开始,可以在 org.hibernate.boot.model.process.spi.MetadataBuildingProcess#handleTypes 中找到获取 TypeContributor 服务的代码。
\n小智 6
我将 JPA 与 Spring 4.3.9 和 Hibernate 5.0.5 一起使用,并使用自定义属性EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS和 Spring LocalContainerEntityManagerFactoryBean 来覆盖 Hibernate BasicTypes。
final Properties jpaProperties = new Properties();
jpaProperties.put(EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS, new TypeContributorList() {
@Override
public List<TypeContributor> getTypeContributors() {
return Lists.newArrayList(new CustomDateTimeTypeContributor());
}
});
final LocalContainerEntityManagerFactoryBean factoryBean = new
LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaProperties(jpaProperties);
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
return factoryBean;
Run Code Online (Sandbox Code Playgroud)
有一个更简单的解决方案-实际上,这只是一行代码。您可以只使用@TypeDef批注,从而避免必须注册自定义类型:
@Entity(name = "Product")
@TypeDef(
name = "bitset",
defaultForType = BitSet.class,
typeClass = BitSetType.class
)
public static class Product {
@Id
private Integer id;
private BitSet bitSet;
Run Code Online (Sandbox Code Playgroud)
有关示例,请参见http://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html中的 “示例11。使用@TypeDef注册自定义类型”。
| 归档时间: |
|
| 查看次数: |
4322 次 |
| 最近记录: |