TL; DR
Ya itu. Ada beberapa cara yang lebih baik untuk melakukan bootstrap Hibernate, seperti yang berikut ini.
Bootstrap asli-hibernasi
Configuration
Objek warisan kurang kuat daripada menggunakan BootstrapServiceRegistryBuilder
, diperkenalkan sejak 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();
Bootstrap JPA
Anda juga dapat melakukan bootstrap Hibernate menggunakan JPA:
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();
Dengan cara ini, Anda sedang membangun EntityManagerFactory
bukan SessionFactory
. Namun, SessionFactory
memperpanjangEntityManagerFactory, so the actual object that's built is a
SessionFactoryImpl` juga.
Kesimpulan
Dua metode bootstrap ini memengaruhi perilaku Hibernate. Saat menggunakan bootstrap asli, Hibernate berperilaku dalam mode lama, yang ada sebelum JPA.
Saat bootstrap menggunakan JPA, Hibernate akan berperilaku sesuai dengan spesifikasi JPA.
Ada beberapa perbedaan antara kedua mode ini:
- Bagaimana mode siram AUTO bekerja dalam hal permintaan SQL asli
- Bagaimana entitas Proxy dibangun. Secara tradisional, Hibernate tidak menekan DB ketika membangun Proxy, tetapi JPA membutuhkan melemparkan
EntityNotFoundException
, oleh karena itu menuntut pemeriksaan DB.
- apakah Anda dapat menghapus entitas yang tidak dikelola
Untuk detail lebih lanjut tentang perbedaan-perbedaan ini, periksa JpaCompliance
kelas.