我正在嘗試使用 CommandLineRunner 訪問底層 Hibernate 資料庫的資訊,以便最終轉儲模式檔案。我需要訪問服務注冊表實體才能做到這一點。
我試圖查看是否可以通過以下代碼從 AutoWired EntityManagerFactory 獲取它:
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();
}
該應用程式給了我這個錯誤:
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
接下來,我嘗試使用以下代碼創建一個構建器:
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);
}
}
這導致了這個錯誤:
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 檔案中定義了我的資料庫配置:
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
任何想法出了什么問題?
uj5u.com熱心網友回復:
似乎 Spring 只是沒有將 Hibernate 注冊ServiceRegistry為 bean。我查看了源代碼,發現它的實體是在SessionFactoryImpl建構式中創建的。
您可以嘗試應用此技巧。
@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);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/439112.html
