[SPRING] 봄 부팅시 모든 테이블 메타 데이터를 얻는 방법 - JPA - 최대 절전 모드?
SPRING봄 부팅시 모든 테이블 메타 데이터를 얻는 방법 - JPA - 최대 절전 모드?
나는 내 스키마에 동적으로 존재하는 모든 테이블의 META 정보를 얻을 필요가있다. 메타 정보는 테이블, 엔티티, 컬럼 이름 등이다.
나는 다음 튜토리얼을 따라 갔다.
https://vladmihalcea.com/how-to-get-the-entity-mapping-to-database-table-binding-metadata-from-hibernate/
위의 링크에서 MetadataExtractorIntegrator.java라는 Integrator를 만들었습니다.
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;
public class MetadataExtractorIntegrator implements org.hibernate.integrator.spi.Integrator {
public static final MetadataExtractorIntegrator INSTANCE = new MetadataExtractorIntegrator();
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) {
}
}
그리고 구성에 따라 내 응용 프로그램에 등록하려고합니다.
application.yml
jpa:
properties:
hibernate.integrator_provider: com.test.ttv.MetadataExtractorIntegrator
그리고 빌드를 시작하는 동안 다음과 같은 예외가 발생합니다.
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.hibernate.jpa.boot.spi.IntegratorProvider
더 많은 StackTrace
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to org.hibernate.jpa.boot.spi.IntegratorProvider
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1710) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1085) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:858) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at testtest(Test.java:31) [main/:na]
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.hibernate.jpa.boot.spi.IntegratorProvider
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.buildBootstrapServiceRegistry(EntityManagerFactoryBuilderImpl.java:339) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:196) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:164) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:51) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:388) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 16 common frames omitted
아무도 나를이 문제를 해결하는 데 도움이 될 수 있습니까 ?? 감사
해결법
-
==============================
1.스프링 부트에서 spring.jpa.properties는 Map
을 가리키므로 String 값만 포함 할 수 있습니다. 스프링 부트에서 spring.jpa.properties는 Map
을 가리키므로 String 값만 포함 할 수 있습니다. 그러나 Hibernate에서 EntityManagerFactoryBuilderImpl이 hibernate.integrator_provider를 읽을 때 클래스 이름이 아닌 IntegratorProvider의 인스턴스를 찾을 것으로 예상되므로 예외가 발생합니다.
그러나 HibernatePropertiesCustomizer를 구현하는 Bean을 추가하여 IntegrationProvider 인스턴스를 Hibernate 속성에 추가 할 수있다.
@Component public class HibernateConfig implements HibernatePropertiesCustomizer { @Override public void customize(Map<String, Object> hibernateProperties) { hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE)); } }
이 저장소에 작업 예제를 만들었습니다.
-
==============================
2.Spring Boot 1.5.x를 사용한다면 "HibernatePropertiesCustomizer"가 존재하지 않습니다.
Spring Boot 1.5.x를 사용한다면 "HibernatePropertiesCustomizer"가 존재하지 않습니다.
여기서 사용할 수있는 솔루션을 찾았습니다. 여기서는 통합자를 사용할 수 없지만 모든 이벤트 수신기를 하나씩 추가 할 수 있습니다. 다음은 내 코드 코드입니다.
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); } }
from https://stackoverflow.com/questions/51501405/how-to-get-the-all-table-metadata-in-spring-boot-jpa-hibernate by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 컨텍스트 초기화에 실패했습니다. NoSuchMethodError : AntPathMatcher.setCaseSensitive () (0) | 2019.05.17 |
---|---|
[SPRING] Spring + SOAPExceptionImpl : 여러 부분 메시지 저장 중 오류가 발생했습니다. (0) | 2019.05.17 |
[SPRING] spring-boot-maven-plugin은 형제 모듈 의존성을 깨뜨린다. (0) | 2019.05.17 |
[SPRING] spring xml을 설정하여 spring을 확장하는 방법 (0) | 2019.05.17 |
[SPRING] @Component Hibernate 클래스 (0) | 2019.05.17 |