Переход на Spring 6, несколько источников данных и менеджеров сущностейJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Переход на Spring 6, несколько источников данных и менеджеров сущностей

Сообщение Anonymous »

Я переношу проект с Spring 5 (Spring Boot 2.x) на Spring 6 (Spring Boot 3.1) и обновляюсь до Java 17. Первоначально это было сделано в Spring 4, и приложение подключается к двум разным базам данных. каждый из них настроен в XML в соответствии с шаблоном, приведенным в этом посте.
Настройка нескольких баз данных с несколькими EntityManagerFactory в данных Spring
У меня возникла проблема при запуске с такой ошибкой
Невозможно разрешить ссылку на bean-компонент «entityManagerFactory» при установке аргумента конструктора.
Но я не знаю, как это исправить . Моя конфигурация выглядит примерно так

Код: Выделить всё

    

























org.hibernate.dialect.Oracle12cDialect
firstEMF




com.example.entity.first











org.hibernate.dialect.Oracle12cDialect
secondEMF




com.example.entity.second



Журнал запуска выглядит так

Код: Выделить всё

...
INFO  c.e.w.MyApp                              : No active profile set, falling back to 1 default profile: "default"
INFO  .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
INFO  .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
INFO  o.s.b.w.e.t.TomcatWebServer              : Tomcat initialized with port(s): 8080 (http)
INFO  o.a.c.c.StandardService                  : Starting service [Tomcat]
INFO  o.a.c.c.StandardEngine                   : Starting Servlet engine: [Apache Tomcat/10.1.10]
INFO  o.a.j.s.TldScanner                       : At least one JAR was scanned for TLDs yet contained no TLDs.  Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them.  Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
INFO  o.a.c.c.C.[.[.[/]                        : Initializing Spring embedded WebApplicationContext
INFO  w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2636 ms
INFO  o.h.j.i.u.LogHelper                      : HHH000204: Processing PersistenceUnitInfo [name: default]
INFO  o.h.Version                              : HHH000412: Hibernate ORM core version 6.2.5.Final
INFO  o.h.c.Environment                        : HHH000406: Using bytecode reflection optimizer
INFO  o.h.b.i.BytecodeProviderInitiator        : HHH000021: Bytecode provider name : bytebuddy
INFO  o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
WARN  o.h.e.j.c.i.ConnectionProviderInitiator  : HHH000181: No appropriate connection provider encountered, assuming application will be supplying connections
WARN  o.h.e.j.e.i.JdbcEnvironmentInitiator     : HHH000342: Could not obtain connection to query metadata

java.lang.UnsupportedOperationException:  The application must supply JDBC connections
at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:44) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:316) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:152) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:34) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:239) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:216) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.model.relational.Database.(Database.java:45) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:230) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:198) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:166) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1380) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1451) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1816) ~[spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) [spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) [spring-beans-6.0.10.jar:6.0.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) [spring-beans-6.0.10.jar:6.0.10]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)  [spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:931) [spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) [spring-context-6.0.10.jar:6.0.10]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) [spring-boot-3.1.1.jar:3.1.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) [spring-boot-3.1.1.jar:3.1.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) [spring-boot-3.1.1.jar:3.1.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-3.1.1.jar:3.1.1]
...

INFO  o.h.b.i.BytecodeProviderInitiator        : HHH000021: Bytecode provider name : bytebuddy
INFO  o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
INFO  j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
INFO  o.h.j.i.u.LogHelper                      : HHH000204: Processing PersistenceUnitInfo [name: default]
INFO  o.h.b.i.BytecodeProviderInitiator        : HHH000021: Bytecode provider name : bytebuddy
INFO  o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
INFO  o.h.b.i.BytecodeProviderInitiator        : HHH000021: Bytecode provider name : bytebuddy
INFO  o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
INFO  j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
INFO  c.e.w.MyApp                              : adding properties resource, /META-INF/MANIFEST.MF
WARN  ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
INFO  j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
INFO  j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
У меня есть объекты DAO, которые реализуют некоторые базовые операции CRUD, а также несколько операций поиска. Если не учитывать операции CRUD, они были выполнены в иерархии, чтобы исключить большое количество дублированного кода, а наследование выглядит так:

Код: Выделить всё

public abstract class AbstractDAO implements DAO {
protected EntityManagerFactory entityManagerFactory;
protected abstract void setEntityManagerFactory(EntityManagerFactory entityManagerFactory);
public EntityManagerFactory getEntityManagerFactory() {
return this.entityManagerFactory;
}
...
}

Код: Выделить всё

public class FirstAbstractDAO  extends AbstractDAO {
@Override
@Autowired
@Qualifier("firstEMF")
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
}

Код: Выделить всё

public class SecondAbstractDAO  extends AbstractDAO {
@Override
@Autowired
@Qualifier("secondEMF")
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
}
Журналы показывают, что они инициализируются, и если я установлю точку останова в setEntityManagerFactory, я ясно увижу, что они инициализируются.
Что я могу' Не могу понять, что именно Spring Boot 3 пытается инициализировать, что приводит к ошибке в этой трассировке

Код: Выделить всё

java.lang.UnsupportedOperationException: The application must supply JDBC connections
at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:44) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:316) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:152) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:34) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:239) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:216) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.model.relational.Database.(Database.java:45) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:230) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.(InFlightMetadataCollectorImpl.java:198) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:166) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1380) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1451) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.0.10.jar:6.0.10]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.10.jar:6.0.10]
...
Если я поставлю точку останова в createContainerEntityManagerFactory, я увижу, что она пытается инициализировать firstEMF. Я подозреваю, что он делает это «слишком рано», поскольку, когда я перехожу к EntityManager.build, все значения конфигурации для firstEMF установлены, но источник данных имеет значение null.
Это кажется, что мне чего-то не хватает в моей конфигурации, но я не могу понять, чего именно. В журнале есть сообщение «Инициализированная JPA EntityManagerFactory» после исключения.
-- РЕДАКТИРОВАНИЕ/Дополнительная информация --
Я установил точку останова в одном из методов getBean в AnnotationConfigServletWebServerApplication, где он пытается разрешить «firstEMF», а также в LocalContainerEntityManagerFactoryBean.setDataSource. Мой XML правильно читается и создает «firstDataSource», и все параметры соединения выглядят правильно прочитанными. Посмотрите на цепочку вызовов: это при инициализации firstEMF. Поэтому теперь я больше озадачен тем, почему позже получаю исключение.
Настройка и использование нескольких источников данных в Spring Boot упоминает использование @Primary, но это при настройке на Java; Я не понимаю, как настроить то же самое только через XML.

Подробнее здесь: https://stackoverflow.com/questions/767 ... y-managers
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»