首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Spring应用程序中获取ServiceRegistry实例?

如何从Spring应用程序中获取ServiceRegistry实例?
EN

Stack Overflow用户
提问于 2022-02-28 18:34:55
回答 1查看 343关注 0票数 0

我试图使用一个CommandLineRunner来访问底层Hibernate数据库的信息,这样我最终可以转储一个模式文件。为此,我需要访问服务注册表实例。

我试着看看是否可以通过以下代码从AutoWired EntityManagerFactory获得它:

代码语言:javascript
复制
package test;

import javax.persistence.EntityManagerFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.ServiceRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class AutoWiredTest implements CommandLineRunner {
  @Autowired
  private EntityManagerFactory emf;
  
  @Override
  public void run(String... args) 
  throws Exception {
    SessionFactoryImplementor sessionFactory = emf.unwrap(SessionFactoryImplementor.class);
    ServiceRegistry serviceRegistry = sessionFactory.getServiceRegistry();
    if( serviceRegistry == null )
      throw new Exception("Service registry is null");
    MetadataSources metadataSources = new MetadataSources(serviceRegistry);
    metadataSources.buildMetadata();
 }

应用程序给出了以下错误:

代码语言:javascript
复制
java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:780) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:761) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.4.jar:2.6.4]
        at test.AutoWiredTest.main(AutoWiredTest.java:31) ~[classes/:na]
Caused by: org.hibernate.HibernateException: Unexpected type of ServiceRegistry [org.hibernate.service.internal.SessionFactoryServiceRegistryImpl] encountered in attempt to build MetadataBuilder
        at org.hibernate.boot.internal.MetadataBuilderImpl.getStandardServiceRegistry(MetadataBuilderImpl.java:113) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at org.hibernate.boot.internal.MetadataBuilderImpl.<init>(MetadataBuilderImpl.java:93) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at org.hibernate.boot.MetadataSources.getMetadataBuilder(MetadataSources.java:146) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at org.hibernate.boot.MetadataSources.buildMetadata(MetadataSources.java:202) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at test.AutoWiredTest.run(AutoWiredTest.java:26) ~[classes/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:777) ~[spring-boot-2.6.4.jar:2.6.4]
        ... 5 common frames omitted

接下来,我尝试用以下代码创建一个构建器:

代码语言:javascript
复制
package test;

import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BuilderTest implements CommandLineRunner {
  @Override
  public void run(String... args) 
  throws Exception {
    new StandardServiceRegistryBuilder().configure().build();
  }
  
  public static void main(String[] args) 
  throws Exception {
    SpringApplication.run(test.BuilderTest.class, args);
  }
}

导致此错误:

代码语言:javascript
复制
java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:780) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:761) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.4.jar:2.6.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.4.jar:2.6.4]
        at test.BuilderTest.main(BuilderTest.java:18) ~[classes/:na]
Caused by: org.hibernate.internal.util.config.ConfigurationException: Could not locate cfg.xml resource [hibernate.cfg.xml]
        at org.hibernate.boot.cfgxml.internal.ConfigLoader.loadConfigXmlResource(ConfigLoader.java:53) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at org.hibernate.boot.registry.StandardServiceRegistryBuilder.configure(StandardServiceRegistryBuilder.java:254) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at org.hibernate.boot.registry.StandardServiceRegistryBuilder.configure(StandardServiceRegistryBuilder.java:243) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final]
        at test.BuilderTest.run(BuilderTest.java:13) ~[classes/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:777) ~[spring-boot-2.6.4.jar:2.6.4]
        ... 5 common frames omitted

它正在寻找一个cfg.xml文件,但我已经在application.properties文件中定义了数据库配置:

代码语言:javascript
复制
hibernate.current_session_context_class=thread
hibernate.format_sql=false
hibernate.show_sql=false
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/marketing
spring.datasource.username=marketing
spring.datasource.password=[PASS]
spring.logging.level.root=ERROR
spring.logging.level.org.hibernate=INFO
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB103Dialect

有什么不对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-28 19:45:27

看起来Spring只是没有将Hibernate ServiceRegistry注册为bean。我查看了源代码,发现它的实例是在SessionFactoryImpl构造函数中创建的。

你可以试着用这个黑客。

代码语言:javascript
复制
@SpringBootApplication
public class AutoWiredTest implements CommandLineRunner {
  @Autowired
  private EntityManagerFactory emf;
  
  @Override
  public void run(String... args) 
  throws Exception {
    SessionFactoryImplementor sessionFactory = emf.unwrap(SessionFactoryImplementor.class);
    ServiceRegistry serviceRegistry = sessionFactory.getServiceRegistry();
  }
  
  public static void main(String[] args) 
  throws Exception {
    SpringApplication.run(AutoWiredTest.class, args);
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71299560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档