JPA/Hibernate get find all Table and Column metadata
How to use Hibernate Metadata to find All columns and tablesGetting the Hibernate's Metadata objec 2021-7-17 06:49:0 Author: blog.gtiwari333.com(查看原文) 阅读量:19 收藏

How to use Hibernate Metadata to find All columns and tables

Getting the Hibernate's Metadata object into the Spring application is tricky. Luckily, Hibernate Provides an Integrator API (org.hibernate.integrator.spi.Integrator) that we can use to customize/interact with Hibernate. Its the same API that Caching, Bean Validation etc library uses to integrate with Hibernate. 

Also, Spring Boot provides HibernatePropertiesCustomizer to link the 'hibernate.integrator_provider' property to Integrator implementation.

Here's how we can configure the Hibernate Integrator to read metadata.

Step 1) create a extractor implementation

This class is a singleton class and does absolutely nothing other than exposing the Metadata and Database. Since this is singleton this class and the database, metadata objects can be statically accessed using MetadataExtractorIntegrator.INSTANCE

import lombok.Data;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;

@Data
public class MetadataExtractorIntegrator implements Integrator {

public static final MetadataExtractorIntegrator INSTANCE =
new MetadataExtractorIntegrator();
private Database database;
private Metadata metadata;

@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sf,
SessionFactoryServiceRegistry sr) {
this.database = metadata.getDatabase();
this.metadata = metadata;
}

@Override
public void disintegrate(SessionFactoryImplementor sf,
SessionFactoryServiceRegistry sr) {
}
}

Step 2) Register the Spring Hibernate Customizer


import org.hibernate.jpa.boot.spi.IntegratorProvider;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Map;

@Configuration
public class HibernateConfig implements HibernatePropertiesCustomizer {
@Override
public void customize(Map<String, Object> hibernateProps) {
hibernateProps.put("hibernate.integrator_provider",
(IntegratorProvider) () -> List.of(MetadataExtractorIntegrator.INSTANCE));
}
}

Step 3) Use MetadataExtractorIntegrator.metadata to extract the metadata

This is a simple Spring Component that uses Metadata.getCollectionBindings and Metadata.getEntityBindings to extract the tables, columns, PK and type

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.boot.Metadata;
import org.hibernate.mapping.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import java.util.Iterator;

@Component
@RequiredArgsConstructor
@Slf4j
public class DBMetadataReader implements InitializingBean {
final EntityManager em;

@Override
public void afterPropertiesSet() {

Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();

//Collection tables
for (Collection c : metadata.getCollectionBindings()) {
log.info("Collection table: {}", c.getCollectionTable().getQualifiedTableName());
for (Iterator<Column> it = c.getCollectionTable().getColumnIterator();
it.hasNext(); ) {
Column property = it.next();
log.info(" {} {} ", property.getName(), property.getSqlType());
}
}

//all entities
for (PersistentClass pc : metadata.getEntityBindings()) {
Table table = pc.getTable();

log.info("Entity: {} - {}", pc.getClassName(), table.getName());

KeyValue identifier = pc.getIdentifier();

//PK
for (Iterator<Selectable> it = identifier.getColumnIterator();
it.hasNext(); ) {
Column column = (Column) it.next();
log.info(" PK: {} {}", column.getName(), column.getSqlType());
}

//property/columns
for (Iterator it = pc.getPropertyIterator();
it.hasNext(); ) {
Property property = (Property) it.next();

for (Iterator columnIterator = property.getColumnIterator();
columnIterator.hasNext(); ) {
Column column = (Column) columnIterator.next();
log.info(" {} {}", column.getName(), column.getSqlType());
}
}
}
}
}

Example Project:

Checkout my sample github project and the source for working example


文章来源: http://blog.gtiwari333.com/2021/07/jpahibernate-get-find-all-table-and.html
如有侵权请联系:admin#unsafe.sh