Spring Boot and JPA project throws JDBC exception - spring

I'm using Spring Boot and Hibernate for my project and my database is MySql. I'm using annotation instead of JPA.
When I am calling the Rest api I am getting response like:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue May 17 11:32:13 CEST 2016
There was an unexpected error (type=Internal Server Error, status=500).
Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed:
And here is my application.properties
spring.datasource.url=jdbc:mysql://x.x.x.x:3306/db_myfme?useUnicode=yes&characterEncoding=UTF-8&characterSetResults=UTF-8
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.connection.characterEncoding=utf-8
spring.jpa.properties.hibernate.connection.CharSet=utf-8
spring.jpa.properties.hibernate.connection.useUnicode=true
server.tomcat.uri-encoding=UTF-8
# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.mail.host=smtp.gmail.com
spring.mail.username= capfme#gmail.com
spring.mail.password= *******
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.smtp.socketFactory.port=587
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.ssl.enable = true
spring.mail.properties.mail.smtp.socketFactory.fallback = false

spring.datasource.testOnBorrow: true
spring.datasource.validationQuery: SELECT 1
spring.jpa.hibernate.ddl-auto=none

Related

H2 database: h2 console not working with spring-boot

I followed the next tutorial for h2 implementation. H2 works well, but the console isn't - the page isn't opened.
I tried many gifts, so my final application.properties looks so:
#Database settings
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.data.jpa.repositories.bootstrap-mode=default
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.datasource.generate-unique-name = false
spring.h2.console.path=/h2-console/
spring.jpa.hibernate.ddl-auto=update
spring.datasource.tomcat.connection-properties=useUnicode=true;characterEncoding=utf-8;
spring.datasource.sql-script-encoding=UTF-8
spring.jpa.open-in-view=false
spring.datasource.initialization-mode=always
#swagger
spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER
#Disable thymeleaf cashing
spring.template.cache = false;
dependencies:
ext {
spring_boot_version = '2.6.6'
}
implementation "org.springframework.boot:spring-boot-starter-parent:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-validation:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:${spring_boot_version}"
implementation "org.springframework.boot:spring-boot-starter-web:${spring_boot_version}"
runtimeOnly "com.h2database:h2:1.4.193"
....
The uri I try to open:
http://localhost:8080/h2-console
Try this:
server.port=8080
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;
Could you try to add the following configuration to the security config?
http.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
Ideally, you need to config (depending on the spring boot version) to allow access to /h2-console URL.
You can also publicise your security configuration so that I can have a look.

Spring Test Wants To Connect to Database

I am trying to write some tests for my application and encountered following problem:
I defined a application-test.yml with folling content:
server:
port: 8085
spring:
security:
oauth2:
resourceserver:
jwt:
# change localhost:8081 with container name
issuer-uri: http://localhost:8081/auth/realms/drivingschool
jwk-set-uri: http://localhost:8081/auth/realms/drivingschool/protocol/openid-connect/certs
keycloak:
realm: drivingschool
auth-server-url: http://localhost:8081/auth
ssl-required: external
resource: client-interface
use-resource-role-mappings: true
credentials:
secret: xxx
bearer-only: true
My test class:
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
#ActiveProfiles("test")
public class StudentControllerTests {
#Autowired
private MockMvc mockMvc;
#Autowired
private StudentService service;
#MockBean
private StudentRepository repository;
#Test
public void contextLoads(){}
//more tests
}
the test all pass green BUT in the log i can see, that my app tries to connect to a database configured in my (basic) application.yml.
ava.sql.SQLNonTransientConnectionException: Could not connect to address=(host=localhost)(port=9005)(type=master) : Socket fail to connect to host:localhost, port:9005. Verbindungsaufbau abgelehnt (Connection refused)
at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:73) ~[mariadb-java-client-2.6.1.jar:na]
at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:192) ~[mariadb-java-client-2.6.1.jar:na]
jpa:
database-platform: org.hibernate.dialect.MariaDBDialect
hibernate:
use-new-id-generator-mappings: false
ddl-auto: create
datasource:
url: jdbc:mariadb://localhost:9005/waterloo
username: waterloo
password: xxx
driver-class-name: org.mariadb.jdbc.Driver
when creating a application-prod.yml and moving all content from application.yml to application-prod.yml it tells me I have to configure a datasource URL
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
I have the following questions:
Do the application.yml files get layered (*-test.yml settings on top of application.yml)?
Why does Spring try to build a connection to my database when I am not setting a datasource on my application-test.yml AND mocking the repository on the test?
Is it normal that Spring trys to establish a connection at this part?
3.1) If not: How to i prevent it from doing so?
Thanks and kind regards!
Failed to determine a suitable driver class
You need to add mariadb driver dependency to your gradle or maven file.
https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client/2.6.2
Make sure that dependency scope is suitable for test
If you already have and its still not working try to clean and rebuild your project.
Your Questions:
Do the application.yml files get layered (*-test.yml settings on top
of application.yml)?
If you add #ActiveProfiles("test") to you TestClass Spring will try to find an application-test.yml and overrrides application.yml properties with the given properties
Why does Spring try to build a connection to my database when I am not
setting a datasource on my application-test.yml AND mocking the
repository on the test?
Thats the magic of spring boot - it has default configurations for everything. You just need to set the Datasource properties and it will create the bean by itself.
Is it normal that Spring trys to establish a connection at this part? 3.1) If not: How to i prevent it from doing so?
You are starting the whole spring context with #SpringBootTest Annotation.
So it will startup all Repositories and try to establish connection to your database. If you don't want spring to startup the database layer you can just use #WebMvcTest
eg:
#RunWith(SpringRunner.class)
#WebMvcTest
#ActiveProfiles("test")
public class StudentControllerTests {
#Autowired
private MockMvc mockMvc;
#Test
public void contextLoads(){}
//more tests
}
Check this out: https://spring.io/guides/gs/testing-web/
If you need to startup the whole SpringContext you can also disable Spring Data AutoConfiguration with:
#SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
Check this out: https://www.baeldung.com/spring-data-disable-auto-config
missed following annotation:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})

Spring Boot 2.0.4 - H2 Database - #SpringBootTest - Failing on Caused by: org.h2.jdbc.JdbcSQLException: Schema "classpath:db/schema.sql" not found

I have built an application with Spring Boot 2.0.4 and integrated with JPA.
Now I want to run some tests with h2 database, but I am unable to execute the Spring Boot tests with h2.
The exceptions are shown below:
Caused by: org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is org.h2.jdbc.JdbcSQLException: Schema "classpath:db/schema.sql" not found [90079-197]
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:58)
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:210)
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.createSchema(DataSourceInitializer.java:104)
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.afterPropertiesSet(DataSourceInitializerInvoker.java:64)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695)
... 74 more
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is org.h2.jdbc.JdbcSQLException: Schema "classpath:db/schema.sql" not found [90079-197]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:46)
... 79 more
Caused by: org.h2.jdbc.JdbcSQLException: Schema "classpath:db/schema.sql" not found [90079-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.engine.Database.getSchema(Database.java:1808)
at org.h2.engine.Session.setCurrentSchemaName(Session.java:1317)
at org.h2.jdbc.JdbcConnection.setSchema(JdbcConnection.java:1989)
at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:423)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:370)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:194)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:460)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:534)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)
... 80 more
And my application-test.properties is:
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.jdbc-url=jdbc:h2:mem:test
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
spring.datasource.initialization-mode=always
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
logging.level.org.hibernate.SQL=debug
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
These exceptions happened when I executed schema.sql, but h2 want to execute this script in schema named "classpath:schema.sql" which is specified in spring.datasource.schema.
It is pretty clear by the exception Not Found that Spring boot is not able to find the schema.sql file.
Simply copy the src/main/resources/db/schema.sql to src/test/resources/db/schema.sql.
Your property should looks like this:
spring.datasource.schema=db/schema.sql
In the class DataSourceInitializer you can see how it is used
public boolean createSchema() {
List<Resource> scripts = getScripts("spring.datasource.schema",
this.properties.getSchema(), "schema");
if (!scripts.isEmpty()) {
if (!isEnabled()) {
logger.debug("Initialization disabled (not running DDL scripts)");
return false;
}
String username = this.properties.getSchemaUsername();
String password = this.properties.getSchemaPassword();
runScripts(scripts, username, password);
}
return !scripts.isEmpty();
}
the method getScripts add the classpath String:
private List<Resource> getScripts(String propertyName, List<String> resources,
String fallback) {
if (resources != null) {
return getResources(propertyName, resources, true);
}
String platform = this.properties.getPlatform();
List<String> fallbackResources = new ArrayList<>();
fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
fallbackResources.add("classpath*:" + fallback + ".sql");
return getResources(propertyName, fallbackResources, false);
}
So you don't have to set it.
Set spring.jpa.defer-datasource-initialization = true in your application.properties file.

Spring Boot Data Initialization

I am trying to insert some test data after my Spring Boot application has started. I have the below configuration in place. I do notice that the sql script is executed before the JPA entities are created resulting in a failure of the insert statement. Is there any other configuration I am missing here? As noted in my configuration I am using Spring Boot with H2 and EclipseLink for JPA.
Reference
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
Configuration
# H2
spring.h2.console.enabled=true
# Datasource
spring.datasource.url=jdbc:h2:mem:testdb;MODE=ORACLE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
# JPA
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.eclipselink.weaving=false
data.sql is placed under /src/main/resources
Logs
2017-09-05 20:37:37,989 [restartedMain ] INFO
o.s.j.d.e.EmbeddedDatabaseFactory - Starting embedded database:
url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false',
username='sa'
2017-09-05 20:37:38,141 [restartedMain ] INFO
j.LocalContainerEntityManagerFactoryBean - Building JPA container
EntityManagerFactory for persistence unit 'default'
2017-09-05 20:37:38,446 [restartedMain ] INFO
o.s.o.j.AbstractEntityManagerFactoryBean - Initialized JPA
EntityManagerFactory for persistence unit 'default'
2017-09-05 20:37:38,510 [restartedMain ] INFO o.s.j.d.i.ScriptUtils
- Executing SQL script from URL [file:/develop/src/data-init/target/classes/data.sql]
error...
Entity
#Entity
#Table(name = "TEMPLATE_CONFIG")
#Data
public class TemplateUser {
#Id
#Column(name = "TEMPLATE_CONFIG_ID", nullable = false)
private Long configId;
#Column(name = "APP_CODE", nullable = false, length = 100)
private String appCode;
...
}
Update
Uploaded a sample project:
https://git.io/v5SWx
Spring-Boot loads data.sql or data-${somthing}.sql
You can do:
spring.datasource.platform=h2.
spring.datasource.data=myscript-test.sql. ( locations can be changed with this property)
I have a project on that way and is working with h2.
And just how last alternative, if you are not able to load the information maybe you can use the CommandLineRunner in your application file with jdbc template.
This is an existing bug in Spring as confirmed here by the Spring Team.
https://github.com/spring-projects/spring-boot/issues/10365

Failed to get driver instance for oracle

I’m trying to connect to my oracle database, I’m using a spring boot configuration together with YAML file, I’ve configured jdbc in pom and jpa, but it still fails to connect.
I’ve tried many different configuration for the url:
1) jdbcUrl=jdbc:oracle:thin://test.test.test:1521
2) jdbcUrl=jdbc:oracle:thin#test.test.test:1521
3) jdbcUrl=jdbc:oracle://test.test.test:1521
4) jdbcUrl=jdbc:oracle#test.test.test:1521
here my application.yml
spring:
profiles: test
datasource:
onlineterminierung:
url: jdbc:oracle: jdbc:oracle:thin://test.test.test:1521
database: test
username: test
password: test
driverClassName: oracle.jdbc.driver.OracleDriver
defaultSchema:
maxPoolSize: 20
hibernate:
hbm2ddl.method: update
show_sql: false
format_sql: true
dialect: org.hibernate.dialect.Oracle10gDialect
and here the DataSource bean:
/*
* Configure HikariCP pooled DataSource.
*/
#Bean
public DataSource dataSource() {
DataSourceProperties dataSourceProperties = dataSourceProperties();
HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create(dataSourceProperties.getClassLoader())
.driverClassName(dataSourceProperties.getDriverClassName()).url(dataSourceProperties.getUrl()).username(dataSourceProperties.getUsername())
.password(dataSourceProperties.getPassword()).type(HikariDataSource.class).build();
dataSource.setMaximumPoolSize(maxPoolSize);
return dataSource;
}
here the pom:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
<scope>test</scope>
</dependency>
here the stack:
HHH000342: Could not obtain connection to query metadata : Failed to get driver instance for jdbcUrl=jdbc:oracle:thin://test.test.test:1521
Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: java.lang.RuntimeException: Failed to get driver instance for jdbcUrl=jdbc:oracle:thin://test.test.test:1521
Caused by: java.sql.SQLException: No suitable driver
Some idea?
Syntax:
jdbc:oracle:thin:#host:port:db","usname","pwd"
#Autowired
DataSource dataSource;
#Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("oracle.jdbc.OracleDriver");
driverManagerDataSource.setUrl("jdbc:oracle:thin:#hostname:1521/dbname");
driverManagerDataSource.setUsername("uname");
driverManagerDataSource.setConnectionProperties(getadditionalJpaProperties());
driverManagerDataSource.setPassword("password");
return driverManagerDataSource;
}
Properties getadditionalJpaProperties() {
Properties properties = new Properties();
// properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
Always use the long form of the connection URL that gives you the flexibility to pass various connection level parameters. A code sample DataSourceSample on GitHub has a sample URL for reference.
jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))";
I ran into this problem. and I was mistakenly ignoring a line of code
driverManagerDataSource.setDriverClassName("oracle.jdbc.OracleDriver");
or in bean config
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
I am using Oracle 11G and Jersey + Boot server running on Websphere

Resources