After the fix apply in spring-orm 6.0.9 for spring boot native as mentioned in ticket numbered https://github.com/spring-projects/spring-framework/issues/30437#event-9210817752
we tried again the same project. but still getting below error :
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.RuntimeException: org.springframework.dao.InvalidDataAccessApiUsageException: Unable to locate persister: com.codingknownsense.oraclespringboot.entity.CustomerRegistration] with root cause
java.lang.IllegalArgumentException: Unable to locate persister: com.codingknownsense.oraclespringboot.entity.CustomerRegistration at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:740) ~[na:na] at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:721) ~[na:na] at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[userprofile-db-sync:na] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:360) ~[na:na]
Comment From: kartik-kaushik
@snicoll Can you please check and update the ticket?
Comment From: snicoll
@kartik-kaushik there's no need to mention me. I saw the issue but I haven't had the time to look at it yet.
Comment From: kartik-kaushik
Hi Team, Any update on this?
Comment From: snicoll
@kartik-kaushik I did follow the link above to try to get back the sample that leads to the exception you've shared above. Downloading the sample again, it looks like unchanged to me.
If you want support, please take the time to share a minimal sample that reproduces the issue. I believe that you should be able to reproduce the issue above without the requirement of Oracle. Thank you.
Comment From: kartik-kaushik
Hi @snicoll sharing the updated link. Kindly find the reproducible sample at: https://drive.google.com/file/d/1MawlfZ9UPtxJ2o9eWrTH5QsYTa39F8Jo/view?usp=sharing
Comment From: snicoll
@kartik-kaushik I've downloaded the sample above and built the image using mvn -Pnative native:compile
. The generated native application starts successfully for me. How can I reproduce the issue? Also very confused about the fact you're using an old Spring Boot version and and old Spring Framework version as well.
Comment From: kartik-kaushik
@snicoll the version that we used are native compatible i hope. Boot is 3.0.4 as we migrated all our other apps to the same version and so we want to use the same. Is the any limitations to this version specifically? Moreover the application built successfully for us as well as native image but when we hit the api, we are getting the exception. Sharing rhe command for the same: curl command: curl --location --request POST 'http://localhost:8080/data/sync' \ --header 'Content-Type: application/json' \ --header 'Authorization: {{BASIC_STRING}}' \ --data-raw '{ "customerNumber": 8834678923, "emailAddressDetails":"kk@gmail.com", "firstName":"kk", "lastName":"kk" }'
Let me know if you need something more to reproduce it.
Comment From: snicoll
Moreover the application built successfully for us as well as native image but when we hit the api, we are getting the exception.
It would have been nice to state that upfront...
Creating the JPA entity manager this way means that AOT has zero chance to pre-process your persistence unit at build time. Paging the data team (@mp911de) to see if they had similar report and if they can offer guidance.
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean customDBEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("CustomDBDataSource") DataSource ds) {
return builder.dataSource(ds)
.packages("com.codingknownsense.oraclespringboot").persistenceUnit("CUSTDB")
.build();
}
Comment From: mp911de
We hadn't had such requests yet. FWIW, Spring Data supports programmatic bean registration for managed types as our AOT processor obtains and inspects the ManagedTypes
bean during AOT processing. For the LocalContainerEntityManagerFactoryBean
bean retrieval this might not be applicable due to the lifecycle and initialization implications.
Comment From: snicoll
@kartik-kaushik apologizes for the delay in triaging this. We do have an infrastructure to externalize the persistence unit scanning in a separate component that is detected and processed by AOT. To make this working in native, you should restructure your code a bit so that the scanning is known upfront.
I've updated your sample as follows and the issue above doesn't occur:
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean customDBEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("CustomDBPersistenceManagedType") PersistenceManagedTypes persistenceManagedTypes,
@Qualifier("CustomDBDataSource") DataSource ds) {
return builder.dataSource(ds)
.managedTypes(persistenceManagedTypes).persistenceUnit("CUSTDB")
.build();
}
@Bean(name = "CustomDBPersistenceManagedType")
public PersistenceManagedTypes customDBPersistenceManagedTypes(ResourceLoader resourceLoader) {
return new PersistenceManagedTypesScanner(resourceLoader).scan("com.codingknownsense.oraclespringboot");
}
The key is to expose a bean of type PersistenceManagedTypes
. You'll need to do that for every entity managers your app has.
We'll use this issue to improve the documentation.