Spring Boot: failed to load JNDI variables into yml configuration file - spring

According to Spring Boot documentation about Externalized configuration, I tried to load a JNDI variable into my yml configuration file, like this:
spring:
# Show or not log for each sql query
jpa:
show-sql: java:global/bc-api-immop/hibernate/show_sql
And it doesn't work.
I have my variable in my JNDI context:
I also tried this:
spring:
# Show or not log for each sql query
jpa:
show-sql
jndi-name: java:global/bc-api-immop/hibernate/show_sql
But, still the same result.
Do you have any idea what I'm doing wrong?
As weird as it sounds, I also have this code, and it works:
spring:
# Set here configurations for the database connection
datasource:
jndi-name: java:jboss/datasources/bc-appli-as400-ds
Edit: When I do this, it works to (so my issue really comes from getting my JNDI variable):
spring:
# Show or not log for each sql query
jpa:
show-sql: true

The way you have written your yaml is the real problem here
The general concept is key: value so by writing show-sql spring boot expects a value of true or false as it appears on Appendix A. Common application properties so it is normal that your property configuration fails and I am pretty sure that this is showing up somewhere in your log files.
On the first example when you write show-sql: java:global/bc-api-immop/hibernate/show_sql you are actually answering the question "Should I show you the generated SQL statements" with "Hi spring Boot this is your datasource" which we both understand it makes no sence to spring boot :)
Your last statement, on the other hand, is correct. You are defining under the yaml collection item datasource the property jndi-name: with value java:jboss/datasources/bc-appli-as400-ds
I would also suggest spending 10 minutes to read this article Learn X in Y minutes
So a correct approach would probably be
spring:
# Set here configurations for the database connection
datasource:
jndi-name: java:jboss/datasources/bc-appli-as400-ds
jpa:
show-sql: true
Let me know if I can help you more

Related

H2: globally_quoted_identifiers seems not be taken into account

I use spring-boot 2.7.6 and H2 2.1.214.
To fix an issue due to the name of some columns that are also keywords in liquibase files (loaded to initialize the H2 database for tests) and entities, I tried to use the globally_quoted_identifiers property as defined here: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#_quoting_options
So I did it like this:
spring:
jpa:
properties:
hibernate:
globally_quoted_identifiers: true
But I still have the same errors due to keywords (org.h2.jdbc.JdbcSQLSyntaxErrorException) so I do not know if I use it correctly?
As a workaround I have to use NON_KEYWORDS=VALUE,KEY but I would like to manage all keywords globally.

How to specify utf8 encoding for db and tables, using embedded database MariaDB in Spring application?

Developing web application I'd like to use an embedded database to store data. However instead of proposed in-memory databases I`d like to prefer to use custom one. My choice is MariaDB. I have been ruled with this article how to get MariaDB as embedded database in my project, everything is fine, database appears, except one thing: I cannot change an encoding for my tables values.
I tried to set additional application properties in my application.yml file, tried to complete connection string with parameters of specifying encoding, but all those stuff didn't work unfortunately :(
May any of you have ever faced with such problem and can help me? Thank you in advance!
My current application.yml is following:
mariaDB4j:
dataDir: ./localMariaDB
port: 3307
databaseName: embeddedDB
spring:
datasource:
url: jdbc:mariaDB://localhost:3307/
username: root
password:
driver-class-name: org.mariadb.jdbc.Driver
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: create
And finally I get exception bellow:
Caused by: java.sql.SQLException: Incorrect string value: '\xD0\x92 \xD1\x80\xD0...' for column 'current_status' at row 1
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.readErrorPacket(AbstractQueryProtocol.java:1688) ~[mariadb-java-client-2.6.2.jar:na]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.readPacket(AbstractQueryProtocol.java:1550) ~[mariadb-java-client-2.6.2.jar:na]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.getResult(AbstractQueryProtocol.java:1513) ~[mariadb-java-client-2.6.2.jar:na]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:318) ~[mariadb-java-client-2.6.2.jar:na]
... 121 common frames omitted
By the way, when I run the application, the connection string which I get looks like jdbc:mysql://localhost:3307/embeddedDB.
I am confused why there is :mysql: instead of :mariadb: as specified in my connection properties. Does it have an influence on my database behavior?
So, I have found the resolution to my issue.
It appeared as usual very simple :)
To change standard character encoding, which MariaDB proposes, I had to specify additional configuration properties before setting up the MariaDB's DataSource.
As this source provides to configure MariaDBSpringService entity to further use in DataSourceconfiguration, it is necessary to extend it (MariaDBSpringService) with some character encoding description utils. So, to specify custom encoding (i.e. to change standard one) I've just added the following lines of code to MariaDBSpringService bean:
service.getConfiguration().addArg("--character-set-server=utf8mb4");
service.getConfiguration().addArg("--collation-server=utf8mb4_general_ci");
In general, the full bean declaration is below:
#Bean
public MariaDB4jSpringService mariaDB4jSpringService(){
MariaDB4jSpringService service = new MariaDB4jSpringService();
service.getConfiguration().addArg("--character-set-server=utf8mb4");
service.getConfiguration().addArg("--collation-server=utf8mb4_general_ci");
return service;
}
Hope, this will help somebody, who further can possibly face with such issue))
Thanks to everybody, who tried to help me!

Why is the placeholder not set properly in hikari.data-source-properties

I am setting the hikari.data-source-properties with a placeholder, but the placeholder value does not get substituted. It is a spring-boot 2.1.4.RELEASE based application. My intention is to set the Session properties so the DBAs can identify my application. Currently I get a default JDBC Thin Client for my connection when I run SELECT PROGRAM FROM V$SESSION from the DB
Below is what I have in my application.yml file
spring:
datasource:
url: "jdbc:oracle:thin:#machine:1521:service_name"
driver-class-name: "oracle.jdbc.driver.OracleDriver"
hikari.data-source-properties:
v$session.program:${spring.application.name}
Below is what I have in my bootstrap.yml file
spring:
application:
name: ms-db-service
When I query the Oracle DB, I notice that the value for program is literally ${spring.application.name}, instead of the expected value ms-db-service
I have tried the below, with same logical result:
Tried redefining the spring.application.name again in the application.yml
Tried using a different locally defined key ${name}
Added the following bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Tried specifying the property as such: spring.datasource.hikari.data-source-properties: v$session.program=${spring.application.name}
I tried the below items to gain more knowledge of the situation:
I tried using a placeholder for spring.datasource.url and that worked fine
I tried to read the value manually using the below code, and that shows the correct values: #Value("${spring.datasource.hikari.data-source-properties}") String propVal;
My conclusion is that HikariCp reads these values before the placeholder substitution is done. I don't understand the relative timing of when the substitution and datasource bean creation happen in the spring-boot bean life-cycle
I am trying to avoid using a bean for hikaricp datasource (not sure if that will even solve the issue), as I don't want to manually build the whole datasource as hikari supports huge number of properties.
So, how can I set the spring.datasource.hikari.data-source-properties in application.yml using a placeholder. And, is there any other way to assign spring.application.name to identify my current db connection?
You have to use it like this:
spring:
datasource:
hikari:
data-source-properties:
"[v$session.program]": ${spring.application.name}

JPA with Multiple database and application.yml

My application (spring-boot) need to access multiple databases.
For some reason, I can't find a propper example using application.yml
This example: http://smasue.github.io/spring-yml-datasources
-> application.yml but not jpa
this example: https://www.baeldung.com/spring-data-jpa-multiple-databases
-> jpa but not application.yml
So I created a very simple project based on this gs: https://spring.io/guides/gs/accessing-data-jpa/
You can find my simple example here: https://github.com/Tyvain/JpaMultipleDatabaseAndApplicationYml
spring:
datasource:
db-1:
url: jdbc:postgresql://10.10.100.100:5432/db1
username: db1
password: db1
driver-class-name: org.postgresql.Driver
db-2:
url: jdbc:postgresql://10.10.100.100:5432/db2
username: db2
password: db2
driver-class-name: org.postgresql.Driver
From here, I am not sure how to affect my repositories to each database.
This example https://www.baeldung.com/spring-data-jpa-multiple-databases is unclear as it's based on properties... and I am not sure how to adapt all code
#PropertySource({ "classpath:persistence-multiple-db.properties" })
[...]
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
How would you assign each repo (CustomerRepositoryDB1 and CustomerRepositoryDB2) to their database ?
Properties and yaml are two absolutely equal means of configuration. The format is only slgihtly different.
You could just replace foo.properties with foo.yml and
com.foobar.var1=value
com.foobar.var2=value2
simply becomes
com.foobar:
var1: value
var2: value2
Plus there is an official Spring Data Repository on Github full of examples. There is even one with two datasources, configured completely in code, no yaml or properties needed:
https://github.com/spring-projects/spring-data-examples/tree/master/jpa/multiple-datasources
In Application.java they exclude the AutoConfig classes and then in each package (Order, Customer), they have a Config class, configuring the datasource. Then there is no need to set the datasource on the repository itself, as that is handled by package scanning with:
factoryBean.setPackagesToScan(OrderConfig.class.getPackage().getName());
in the config. To reiterate: it's datasource per java package, no annotation on the Repository needed.

Show Sql in Jhipster 4.4.1

I added a new connection to my Jhipster application:
data:
mongodb:
uri: mongodb://localhost:27017
database: crm
datasources:
elser:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/elser
name: elser
username: elser
password: elser
I want to see in the sql logs that my connection to Postgres generates.
I have tested by adding the following code in 'application-dev.yml':
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
or:
jpa:
show_sql: true
format_sql: true
But neither option worked for me.
Can somebody help me.
Thank you
According to spring docs setting spring.jpa.show-sql=true should do the trick.
Have you checked if it appears in stdout?
From the spring boot docs:
# JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration)
spring.data.jpa.repositories.enabled=true # Enable JPA repositories.
spring.jpa.database= # Target database to operate on, auto-detected by default. Can be alternatively set using the "databasePlatform" property.
spring.jpa.database-platform= # Name of the target database to operate on, auto-detected by default. Can be alternatively set using the "Database" enum.
spring.jpa.generate-ddl=false # Initialize the schema on startup.
spring.jpa.hibernate.ddl-auto= # DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Default to "create-drop" when using an embedded database, "none" otherwise.
spring.jpa.hibernate.naming.implicit-strategy= # Hibernate 5 implicit naming strategy fully qualified name.
spring.jpa.hibernate.naming.physical-strategy= # Hibernate 5 physical naming strategy fully qualified name.
spring.jpa.hibernate.naming.strategy= # Hibernate 4 naming strategy fully qualified name. Not supported with Hibernate 5.
spring.jpa.hibernate.use-new-id-generator-mappings= # Use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.
spring.jpa.open-in-view=true # Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the thread for the entire processing of the request.
spring.jpa.properties.*= # Additional native properties to set on the JPA provider.
spring.jpa.show-sql=false # Enable logging of SQL statements.

Resources