Spring boot unable to determine jdbc url from datasouce (mysql) - java

I am trying to load a MySQL database into a spring boot application but when I start the application I am getting those error messages:
2018-07-17 13:46:31.426 WARN 2120 --- [ restartedMain] o.s.b.a.orm.jpa.DatabaseLookup : Unable to determine jdbc url from datasource
org.springframework.jdbc.support.MetaDataAccessException: Could not get Connection for extracting meta-data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: 'url' not set
Although I have set the url property in application.properties : spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
Can anyone help me figure this one out?
Edit: Here is my Main class:
package com.randomsoft.checkoff;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class CheckoffApplication {
public static void main(String[] args) {
SpringApplication.run(CheckoffApplication.class, args);
}
}

can you try by removing
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
also try to add all below jdbc properties,
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase?verifyServerCertificate=false&useSSL=false&requireSSL=false
spring.datasource.username=<username>
spring.datasource.password=<password>
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=update

just try to append this line in your config class
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

Most of the answers recommend excluding DataSourceAutoConfiguration, and I agree with the approach, but what they don't tell is that besides the programmatic way via annotation #EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}), we also have the option of setting it via properties in the following manner which is useful when annotating an application class is not an option.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

You should name property file: application.properties or application.yml

Related

How do I resolve spring configuration property without #ConfigurationProperties?

I'm using Java 8 and Spring Boot. And I'm trying to solve the warning "Cannot resolve configuration property" from IDEA:
(application.properties)
But for this param I don't have any #ConfigurationProperties class to be handled by the "spring-boot-configuration-processor"
I'm only using this param like this:
import org.springframework.beans.factory.annotation.Value;
#Value("${some.param}")
private String param;
I tried to create de metadata file manually but that didn't solve the problem either.
Does anyone have a tip for this?
This is my Application Class:
#SpringBootApplication
#EnableConfigurationProperties
#ComponentScan(basePackages = {"com.sample"})
#ConfigurationPropertiesScan
#EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Looks like you can use additional metadata for this. Although it would be nice to automatically generate this from the #Value (or similar) annotation automatically...
https://docs.spring.io/spring-boot/docs/current/reference/html/configuration-metadata.html#appendix.configuration-metadata.annotation-processor.adding-additional-metadata

Spring DataSource password in separate properties file causes "Failed to determine a suitable driver class"

I have the following Spring configuration
myprefix.systems[0].name=Some System
myprefix.systems[0].datasource.driverclassname=oracle.jdbc.OracleDriver
myprefix.systems[0].datasource.url=jdbc:oracle:thin:#foo:1521/bar
myprefix.systems[0].datasource.username=username
myprefix.systems[0].datasource.password=password
Which is configured into the following class (annotations are lombok and Spring).
#Configuration
#ConfigurationProperties("myprefix")
public class SystemConfig {
#Getter
#Setter
public static class ConfiguredSystem {
private final DataSourceProperties datasource = new DataSourceProperties();
private String name;
public JdbcTemplate getTemplate() {
return new JdbcTemplate(datasource.initializeDataSourceBuilder().build());
}
}
#Getter
private final List<ConfiguredSystem> systems = new ArrayList<>();
#Bean
public List<ConfiguredSystem> allSystems() {
return Collections.unmodifiableList(tradingSystems);
}
}
This works just fine when all the properties are in one application.properties file. The application starts up properly.
I am trying to move the password line into it's own application-secret.properties file, and keep the other properties in the main application.properties file.
myprefix.systems[0].datasource.password=password
I run with
-Dspring.config.location="C:/my/app/dir/conf/"
-Dspring.profiles.active=secret
However, when I do this I get the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (the profiles secret are currently active).
| o.s.b.d.LoggingFailureAnalysisReporter [main]
After putting a breakpoint in getTemplate, it seems the DataSourceProperties only contains the password and none of the other properties. I presume Spring cannot do list comprehension (for lack of a better term), myprefix.systems[0]... across different files?
This won't answer why the initial solution (merging myprefix.systems[0].datasource.password) did not work, but you may solve your problem by:
Creating a db.password property in the application-secret.properties
Use ${db.password} in application.properties.

Spring boot connect with existing JDBC Connection

Spring boot provided it's own database connection according to configuration in application.properties. But here I have a service which provided me an object of javax.sql.Connection type.
src/main/resources/application.properties
server.port=9090
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
Here is code for repository
package com.example.springbootdemo.repositories;
import org.springframework.data.repository.CrudRepository;
import com.example.springbootdemo.model.Box;
public interface BoxRepository extends CrudRepository<Box, Long> {
}
Code for controller
package com.example.springbootdemo.controllers;
import com.example.springbootdemo.model.Box;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.springbootdemo.repositories.BoxRepository;
#RestController
public class BoxController {
#Autowired
BoxRepository boxrepository;
#PostMapping("/box")
public Box addBox(Box box){
return this.boxrepository.save(box);
}
}
Here when I am calling save function of JPA repository it saves the object using db object which it is calculating by using some of its own wrapper.
But I have to use a jar which gives me Database connection. Instead of configuration in src/main/resources/application.properties, I have to use connection object returned from this jar. Now I'll need to override the connection object that spring boot is using internally. I am not able to figure out how I can do this.
you have this path : src//main//resoruces//application.properties
and here you need to configure

Spring Boot Test: #TestPropertySource not overriding #EnableAutoConfiguration

I am using Spring Data LDAP to get user data from an LDAP server.
My file structure looks like this:
main
java
com.test.ldap
Application.java
Person.java
PersonRepository.java
resources
application.yml
schema.ldif
test
java
Tests.java
resources
test.yml
test_schema.ldif
And here is my test class:
import com.test.ldap.Person;
import com.test.ldap.PersonRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {PersonRepository.class})
#TestPropertySource(locations = "classpath:test.yml")
#EnableAutoConfiguration
public class Tests {
#Autowired
private PersonRepository personRepository;
#Test
public void testGetPersonByLastName() {
List<Person> names = personRepository.getPersonNamesByLastName("Bachman");
assert(names.size() > 0);
}
}
The problem is, Spring Boot is loading the application.yml and schema.ldif files instead of my test YAML and LDIF files, despite the fact that my #TestPropertySource annotation is explicitly listing test.yml. This seems to be due to the auto configuration, which I would prefer to use for convenience.
I would expect #TestPropertySource to take higher precedence than the auto configuration, but that does not seem to be the case. Is this a bug in Spring, or am I misunderstanding something?
For the record, here is my test.yml file (it does specify test_schema.ldif):
spring:
ldap:
# Embedded Spring LDAP
embedded:
base-dn: dc=test,dc=com
credential:
username: uid=admin
password: secret
ldif: classpath:test_schema.ldif
port: 12345
validation:
enabled: false
So I was able to work around this by manually specifying the properties needed to make use of the LDIF file. This is because, according to the #TestPropertySource documentation, inlined properties have higher preferences than property files.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {PersonRepository.class})
#TestPropertySource(properties =
{"spring.ldap.embedded.ldif=test_schema.ldif", "spring.ldap.embedded.base-dn=dc=test,dc=com"})
#EnableAutoConfiguration
public class Tests {
//...
}
This is not the best workaround, however: what if I had more than just two properties I needed to define? It would be impractical to list them all there.
Edit:
Renaming my test.yml file to application.yml so it overrides the production file that way did the trick. As it turns out, the TestPropertySource annotation only works for .properties files.
I discovered that YML files DO NOT work with #TestPropertySource annotation.
A clean way around this is to use #ActiveProfile. Assuming that your YML file with test properties is called
application-integration-test.yml
then you should use the annotation like this
#ActiveProfile("integration-test")

Spring Boot JPA: How do I connect multiple databases?

I currently have one database connected and it is working. I would like to connect another (and eventually 2 more) databases. How do I do so? There should be a solution using only annotations and properties files.
I read this
Profile Specific Properties
and it sort of helps but I still don't know how switch from one profile to the other in the code during runtime. I'm assuming I need to be connected to one profile at a time before I try to retrieve/persist things from different databases.
I also read this question, How to use 2 or more databases with spring?, but I dont know how it works too well/ if it will apply. I'm not using a controller class and I dont know what that does. I'm also not sure how the config class they mention in the answer actually connects to the specific DO.
This is my application.properties file: (marked out username and password but its there in my file)
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.default_schema=dbo
hibernate.packagesToScan=src.repositories.LMClientRepository.java
spring.jpa.generate-ddl=true
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
spring.datasource.username=***
spring.datasource.password=***
spring.datasource.url=jdbc:sqlserver://schqvsqlaod:1433;database=dbMOBClientTemp;integratedSecurity=false;
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.database=dbMOBClientTemp
spring.jpa.show-sql=true
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
This is my application file:
package testApplication;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import fileRetrieval.InputFileParse;
import lmDataObjects.LMClientDO;
import lmDataObjects.LoadMethodDO;
import repositories.LMClientRepository;
import repositories.LoadMethodRepository;
#SpringBootApplication
#EnableJpaRepositories(basePackageClasses = LoadMethodRepository.class)
#EntityScan(basePackageClasses = LoadMethodDO.class)
#EnableCaching
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner demo(LoadMethodRepository lm_repo, LMClientRepository lmc_repo) {
return (args) -> {
List<LMClientDO> lmlist = InputFileParse.getMultiGroupfile();
List<String> uniqueMediaIds = new ArrayList(InputFileParse.getUniqueMediaIds());
for (int i = 0; i < InputFileParse.getUniqueMediaIds().size(); i ++){
lm_repo.save(new LoadMethodDO(uniqueMediaIds.get(i)));
}
for (int i = 0; i < lmlist.size(); i++){
lmc_repo.save(new LMClientDO(lmlist.get(i).getClientId(), lmlist.get(i).getMediaId()));
}
//Here is where I would like to do stuff with data from the other database that I have not connected yet
};
}
}
I also made a new properties file called application-MTS.properties and I put data for the new database in there. Still unsure of what to do with it.
spring.datasource.username=***
spring.datasource.password=***
spring.datasource.url=jdbc:sqlserver://SCHQVSQLCON2\VSPD:1433;database=dbMTS;integratedSecurity=false;
You will need to define multiple DataSource beans that each represent the various database connection resources you plan to use.
You will then need to add a TransactionManager and EntityManagerFactory bean definition for each of those DataSource beans.
If you intend to have each DataSource participate in a JTA transaction, you'll need to also consider configuring a JTA transaction manager rather than individual resource local transaction managers.

Categories

Resources