I need to get META information of All the tables present in my schema dynamically , Meta infos are such as table , entity ,column name etc.
I have f
If you are using Springboot 1.5.x, The "HibernatePropertiesCustomizer" is not exist.
I found a solution usable from here. You can not use integrator here, but you can add all the event listeners one by one. below is my code code:
public class RootAwareInsertEventListener implements PersistEventListener {
public static final RootAwareInsertEventListener INSTANCE = new RootAwareInsertEventListener();
@Override
public void onPersist(PersistEvent event) throws HibernateException {
final Object entity = event.getObject();
if (entity instanceof RootAware) {
RootAware rootAware = (RootAware) entity;
Object root = rootAware.getRoot();
event.getSession().lock(root, LockMode.OPTIMISTIC_FORCE_INCREMENT);
log.info("Incrementing {} entity version because a {} child entity has been inserted",
root, entity);
}
}
@Override
public void onPersist(PersistEvent event, Map createdAlready)
throws HibernateException {
onPersist(event);
}
}
@Component
public class HibernateListenerConfigurer {
@PersistenceUnit
private EntityManagerFactory emf;
@PostConstruct
protected void init() {
SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PERSIST).appendListener(RootAwareInsertEventListener.INSTANCE);
registry.getEventListenerGroup(EventType.FLUSH_ENTITY).appendListener(RootAwareUpdateAndDeleteEventListener.INSTANCE);
}
}
In org.springframework.orm.hibernate5.LocalSessionFactoryBean
, there is a variable argument setter method for hibernateIntegrators
which will accept one or more instances of org.hibernate.integrator.spi.Integrator
So in org.springframework.orm.hibernate5.LocalSessionFactoryBean
configuration add the below property
<property name="hibernateIntegrators" ref="metadataExtractorIntegrator" />
and make the Integrator
as managed bean
package com.test.ttv;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.springframework.stereotype.Component;
@Component
public class MetadataExtractorIntegrator implements org.hibernate.integrator.spi.Integrator {
private Database database;
private Metadata metadata;
public Database getDatabase() {
return database;
}
public Metadata getMetadata() {
return metadata;
}
@Override
public void integrate(
Metadata metadata,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
this.database = metadata.getDatabase();
this.metadata = metadata;
}
@Override
public void disintegrate(
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
}
}
In Spring Boot, spring.jpa.properties
points to a Map<String, String>, so it can only contain String
values.
However in Hibernate, when the EntityManagerFactoryBuilderImpl reads hibernate.integrator_provider
it expects to find an instance of IntegratorProvider
and not a Class name, hence the exception.
You can however add a bean that implements HibernatePropertiesCustomizer
to add the IntegrationProvider
instance to the Hibernate properties:
@Component
public class HibernateConfig implements HibernatePropertiesCustomizer {
@Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("hibernate.integrator_provider",
(IntegratorProvider) () -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE));
}
}
I have created a working example in this repository.