spring-data-jpa: Native Image Fails w/ Multiple DataSources
It looks to me like the references configured on `@EnableJpaRepositories` aren't being applied correctly. I suspect that this is a Spring Data JPA bug but it could also be a Spring Framework problem. @matthenry87 please open a Spring Data JPA issue and we can take things from there.
_Originally posted by @wilkinsona in https://github.com/spring-projects/spring-boot/issues/33656#issuecomment-1369838626_
Trying to do all of the groundwork for our teams to start using native images. We use multiple data sources in over half of our applications.
Example project: https://github.com/matthenry87/native-image-multiple-datasource-testing
Spring Boot 3.0.1
GraalVM 22.3.0 Java 17 CE Java version info: ‘17.0.5+8-jvmci-22.3-b08’ C compiler: gcc (linux, x86_64, 9.4.0) Garbage collector: Serial GC
Using GraalVM native-image directly via mvn native:compile -Pnative -DskipTests
Error:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.1)
2022-12-29T19:13:40.616-07:00 INFO 30729 --- [ main] o.m.nativetesting.api.ApiApplication : Starting AOT-processed ApiApplication using Java 17.0.5 with PID 30729 (/mnt/c/workspace/native-image-multimodule-testing/api/target/api started by matt in /mnt/c/workspace/native-image-multimodule-testing)
2022-12-29T19:13:40.617-07:00 INFO 30729 --- [ main] o.m.nativetesting.api.ApiApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-29T19:13:40.631-07:00 WARN 30729 --- [ main] o.s.c.support.GenericApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'db1Service': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'fooEntityRepository': Unexpected exception during bean creation
2022-12-29T19:13:40.633-07:00 ERROR 30729 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.matthenry87.nativetesting.persistence.db1.Db1Service required a single bean, but 2 were found:
- db1EntityManagerFactory: defined by method 'db1EntityManagerFactory' in null
- db2EntityManagerFactory: defined by method 'db2EntityManagerFactory' in null
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Funny thing, is that the Db1Service injects a single repository class, not an EntityManager.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 28 (21 by maintainers)
Thank you all for your patience and sorry it took so long. We have a fix for this (see https://github.com/spring-projects/spring-framework/issues/30476) that is being reviewed and will be part of the next framework release in June.
Sorry, my bad, I was under the impression of missing hints causing this issue, however, it is the Spring Framework AOT persistence context injection causing that issue. We still need to sort out the AOT processing issue as the persistence context is skipped by Spring Framework if the property has been set.
Once the above two issues are fixed (draft PR’s already in place) the app still requires hints to assign the domain types to the
PersistenceUnitviaemf.setManagedTypes(PersistenceManagedTypes.of("org.matthenry87.nativetesting.api.db1.FooEntity"));andemf.setManagedTypes(PersistenceManagedTypes.of("org.matthenry87.nativetesting.api.db2.BarEntity"));in theDB*Configclasses. With the above in place (plus some additional hikari hints) the provided example worked.Thanks a lot Andy. We currently register the Repository AOT processors only once per Spring Data module. This imposes the limitation that only one
@Enable${MODULE}Repositoriesannotation configuration is considered per${MODULE}. It also explains why the second instance of@EnableJpaRepositoriesisn’t caught.Let me take this to the team so we can explore options to work around this issue.
Upgrading to Spring Framework 6.1/Spring Boot 3.2 fixed the issue.
In AOT mode startup (if the Datasource fails) Hibernate fails with:
If the data source works, then the application starts up properly.
In native image mode, startup fails with:
After adding hints for
HikariConfig, we’re back toAfter configuring
PersistenceManagedTypesfor both entity manager factories, the native image mode works.I added:
with the respective package configuration to each
@Configurationclass.Therefore, closing this issue.
Another user with what appears to be the same problem: https://github.com/spring-projects/spring-boot/issues/37749.
So the problem described above has been fixed in
6.0.10-SNAPSHOT. I’ve upgraded the original sample (thank you for that @matthenry87!) and it goes further but fail at runtime due to a missing hint. I’ve created https://github.com/spring-projects/spring-boot/issues/35408 to fix that.In the meantime, you can workaround by exposing a more specific type for the datasource (something you should do anyway, regardless of this issue, see https://docs.spring.io/spring-framework/reference/core/aot.html#aot.bestpractices.bean-type.
Changing the definition of the two datasource of something like the following helps:
The next problem is:
@mp911de I wonder if the above is something that should be investigated by Spring Data still.
I am also waiting for this issue to be resolved: it s sad to not be able to use spring native just because there is no support for multiple datasources… Thanks for the work anyway
Aw bummer, I was excited when I saw your comment 😃 Will continue to monitor for updates here.
Same error with 3.0.2:
and