TL; DR
是的。有一些更好的方法来引导Hibernate,如下所示。
休眠本机引导程序
Configuration
与使用BootstrapServiceRegistryBuilder
Hibernate 4之后引入的相比,旧版对象的功能不那么强大:
final BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder()
.enableAutoClose();
Integrator integrator = integrator();
if (integrator != null) {
bsrb.applyIntegrator( integrator );
}
final BootstrapServiceRegistry bsr = bsrb.build();
final StandardServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder(bsr)
.applySettings(properties())
.build();
final MetadataSources metadataSources = new MetadataSources(serviceRegistry);
for (Class annotatedClass : entities()) {
metadataSources.addAnnotatedClass(annotatedClass);
}
String[] packages = packages();
if (packages != null) {
for (String annotatedPackage : packages) {
metadataSources.addPackage(annotatedPackage);
}
}
String[] resources = resources();
if (resources != null) {
for (String resource : resources) {
metadataSources.addResource(resource);
}
}
final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder()
.enableNewIdentifierGeneratorSupport(true)
.applyImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
final List<Type> additionalTypes = additionalTypes();
if (additionalTypes != null) {
additionalTypes.stream().forEach(type -> {
metadataBuilder.applyTypes((typeContributions, sr) -> {
if(type instanceof BasicType) {
typeContributions.contributeType((BasicType) type);
} else if (type instanceof UserType ){
typeContributions.contributeType((UserType) type);
} else if (type instanceof CompositeUserType) {
typeContributions.contributeType((CompositeUserType) type);
}
});
});
}
additionalMetadata(metadataBuilder);
MetadataImplementor metadata = (MetadataImplementor) metadataBuilder.build();
final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
Interceptor interceptor = interceptor();
if(interceptor != null) {
sfb.applyInterceptor(interceptor);
}
SessionFactory sessionFactory = sfb.build();
JPA引导程序
您还可以使用JPA引导Hibernate:
PersistenceUnitInfo persistenceUnitInfo = persistenceUnitInfo(getClass().getSimpleName());
Map configuration = properties();
Interceptor interceptor = interceptor();
if (interceptor != null) {
configuration.put(AvailableSettings.INTERCEPTOR, interceptor);
}
Integrator integrator = integrator();
if (integrator != null) {
configuration.put(
"hibernate.integrator_provider",
(IntegratorProvider) () -> Collections.singletonList(integrator));
}
EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder =
new EntityManagerFactoryBuilderImpl(
new PersistenceUnitInfoDescriptor(persistenceUnitInfo),
configuration
);
EntityManagerFactory entityManagerFactory = entityManagerFactoryBuilder.build();
这样,您将构建EntityManagerFactory
而不是SessionFactory
。但是,也SessionFactory
扩展了EntityManagerFactory, so the actual object that's built is a
SessionFactoryImpl`。
结论
这两种引导方法会影响休眠行为。使用本机引导程序时,Hibernate会以旧模式运行,该模式早于JPA。
当使用JPA引导时,Hibernate将按照JPA规范运行。
这两种模式之间存在一些差异:
- 关于本机SQL查询,自动刷新模式如何工作
- 实体代理的构建方式。传统上,Hibernate在构建Proxy时不会命中数据库,但是JPA需要抛出
EntityNotFoundException
,因此需要进行数据库检查。
- 是否可以删除非托管实体
有关这些差异的更多详细信息,请查看JpaCompliance
课程。