How to get the All table metadata in spring boot - JPA - hibernate?

后端 未结 3 452
逝去的感伤
逝去的感伤 2021-01-14 04:09

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

相关标签:
3条回答
  • 2021-01-14 04:59

    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);
    
        }
    }
    
    0 讨论(0)
  • 2021-01-14 05:04

    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) {
    
            }
        }
    
    0 讨论(0)
  • 2021-01-14 05:06

    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.

    0 讨论(0)
提交回复
热议问题