Start with a new application generated from Spring Initializer having: - maven - Java 17 - GraalVM Native Support - Spring Data JPA
Configure in application.yml the connection to mysql:
spring:
jpa:
database: mysql
database-platform: org.hibernate.dialect.MySQLDialect
hibernate:
ddl-auto: none
dialect: org.hibernate.dialect.MySQLDialect
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
datasource:
url: jdbc:mysql://localhost:9090/db?useSSL=false&allowPublicKeyRetrieval=true
username: user
password: password
Add dependency to mysql in pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Add a registrar to resolve issues related to naming similar to this:
@SpringBootApplication
@ImportRuntimeHints(HibernateDemoApplication.Registrar.class)
public class HibernateDemoApplication {
public static void main(String[] args) {
SpringApplication.run(HibernateDemoApplication.class, args);
}
static class Registrar implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
ReflectionHints reflectionHints = hints.reflection();
Arrays.asList( MySQLDialect.class, PhysicalNamingStrategyStandardImpl.class)
.forEach(c-> registerForReflection(c, reflectionHints));
}
private void registerForReflection(Class classR, ReflectionHints hints){
Arrays.stream(classR.getConstructors()).forEach(c->hints.registerType(classR).registerConstructor(c,ExecutableMode.INVOKE));
}
After compiling native, on runtime I receive the following errors:
2022-11-04T17:37:01.346+02:00 ERROR 23092 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1753) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1131) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:906) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at com.example.demo.HibernateDemoApplication.main(HibernateDemoApplication.java:20) ~[hibernate-demo.exe:na]
Caused by: java.lang.ExceptionInInitializerError: null
at com.mysql.cj.Constants.<clinit>(Constants.java:49) ~[na:na]
at com.mysql.cj.util.Util.<clinit>(Util.java:67) ~[na:na]
at com.mysql.cj.conf.ConnectionUrl$Type.getImplementingInstance(ConnectionUrl.java:241) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.conf.ConnectionUrl$Type.getConnectionUrlInstance(ConnectionUrl.java:211) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.conf.ConnectionUrl.getConnectionUrlInstance(ConnectionUrl.java:280) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:195) ~[hibernate-demo.exe:8.0.31]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[na:na]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) ~[hibernate-demo.exe:na]
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[hibernate-demo.exe:na]
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) ~[na:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[na:na]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100) ~[na:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[hibernate-demo.exe:na]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:177) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:36) ~[na:na]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[na:na]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:255) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:230) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.boot.model.relational.Database.<init>(Database.java:44) ~[na:na]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:218) ~[na:na]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191) ~[na:na]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:138) ~[na:na]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421) ~[hibernate-demo.exe:6.1.5.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66) ~[na:na]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1799) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1749) ~[hibernate-demo.exe:6.0.0-RC3]
... 15 common frames omitted
Caused by: java.lang.RuntimeException: Can't load resource bundle due to underlying exception java.util.MissingResourceException: Can't find bundle for base name com.mysql.cj.LocalizedErrorMessages, locale en_US
at com.mysql.cj.Messages.<clinit>(Messages.java:60) ~[na:na]
... 49 common frames omitted
Caused by: java.util.MissingResourceException: Can't find bundle for base name com.mysql.cj.LocalizedErrorMessages, locale en_US
at java.base@17.0.5/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045) ~[hibernate-demo.exe:na]
at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1683) ~[hibernate-demo.exe:na]
at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1586) ~[hibernate-demo.exe:na]
at java.base@17.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1549) ~[hibernate-demo.exe:na]
at java.base@17.0.5/java.util.ResourceBundle.getBundle(ResourceBundle.java:858) ~[hibernate-demo.exe:na]
at com.mysql.cj.Messages.<clinit>(Messages.java:58) ~[na:na]
... 49 common frames omitted
If we further register the resource file like this:
hints.resources().registerPattern("com/mysql/cj/LocalizedErrorMessages.properties");
another error is received:
2022-11-04T17:53:16.384+02:00 WARN 28272 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata
com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: com.mysql.cj.exceptions.CJException cannot be cast to com.mysql.cj.exceptions.WrongArgumentException
at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:596) ~[na:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:582) ~[na:na]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100) ~[na:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[hibernate-demo.exe:na]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:177) ~[na:na]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:36) ~[na:na]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[na:na]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:255) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:230) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.boot.model.relational.Database.<init>(Database.java:44) ~[na:na]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:218) ~[na:na]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191) ~[na:na]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:138) ~[na:na]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350) ~[hibernate-demo.exe:6.1.5.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421) ~[hibernate-demo.exe:6.1.5.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66) ~[na:na]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1799) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1749) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1131) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:906) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[hibernate-demo.exe:6.0.0-RC3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[hibernate-demo.exe:3.0.0-SNAPSHOT]
at com.example.demo.HibernateDemoApplication.main(HibernateDemoApplication.java:20) ~[hibernate-demo.exe:na]
Caused by: java.lang.ClassCastException: com.mysql.cj.exceptions.CJException cannot be cast to com.mysql.cj.exceptions.WrongArgumentException
at com.mysql.cj.util.Util.getInstance(Util.java:169) ~[na:na]
at com.mysql.cj.util.Util.getInstance(Util.java:174) ~[na:na]
at com.mysql.cj.conf.ConnectionUrl$Type.getImplementingInstance(ConnectionUrl.java:241) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.conf.ConnectionUrl$Type.getConnectionUrlInstance(ConnectionUrl.java:211) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.conf.ConnectionUrl.getConnectionUrlInstance(ConnectionUrl.java:280) ~[hibernate-demo.exe:8.0.31]
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:195) ~[hibernate-demo.exe:8.0.31]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[na:na]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) ~[hibernate-demo.exe:na]
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[hibernate-demo.exe:na]
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) ~[na:na]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[na:na]
... 38 common frames omitted
The connection was working fine on Spring Boot 2.7.4 with spring-native
Comment From: wilkinsona
I believe that upgrading to 0.9.17 of the NBT plugin will fix this.
Unfortunately, MySQL changed the coordinates of their JDBC driver in the latest release. As a result, mysql:mysql-connector-java now relocates to com.mysql:mysql-connector-j and the GraalVM reachability metadata is lost. That's been fixed in 0.2.4 of the reachability metadata which NBT 0.9.17 uses by default.
You haven't told use the version of Boot you're using, but upgrading to 3.0.0-SNAPSHOT should fix it as it uses 0.9.17 by default. Alternatively, you could use Boot 3.0.0-RC1 and override the plugin's version manually. Please give one of these a try and let us know how you get on.
Comment From: eugeniace
I have generated the project using 3.0.0-SNAPSHOT version
Comment From: wilkinsona
Please build with -U to make sure you have the latest bits. We only upgraded to NBT 0.9.17 earlier today. You can check your build's output to see which version of the plugin it's using:
[INFO] --- native-maven-plugin:0.9.17:compile (default-cli) @ demo-aot-native ---
Comment From: eugeniace
Indeed, it was using version 0.9.16. After running with -U flag it was all fine. Thank you for your help and sorry for opening a false issue.
Comment From: wilkinsona
Great. Thanks for letting us know.