I am using spring boot and spring-jdbc-starter.
I am trying to connect to specific edition in oracle database. For example, it is EDITION_X.
Then, I am trying to create a datasource via yaml file.
spring:
datasource:
driverClassName: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:#ip:port/NAME
username: user
password: password
connectionProperties:
- ORA_EDITION:EDITION_X
Another way, I am trying to configure it via java-code.
public DataSource oracleDataSource() throws SQLException {
OracleDataSource oracleDataSource = new OracleDataSource();
Properties properties = new Properties();
properties.setProperty("ORA_EDITION", "EDITION_X");
oracleDataSource.setConnectionProperties(properties);
oracleDataSource.setURL("jdbc:oracle:thin:#ip:port/NAME");
oracleDataSource.setUser("user");
oracleDataSource.setPassword("");
oracleDataSource.setDriverType("oracle.jdbc.driver.OracleDriver");
return oracleDataSource;
}
From actuator, it seems, that properties are loaded. But the edition is still default.
Any ideas, how to connect to specific edition in oracle database?
In poor JDBC connection you should provide "oracle.jdbc.editionName" propertie. In spring it also should work.
properties.setProperty("oracle.jdbc.editionName", "EDITION_X");
If you one the check if it's work use this query.
select sys_context('userenv', 'current_edition_name') from dual
Related
I have an Spring boot application that runs several services and uses oracle database. The database is maintained properly, indexes also added up, and when executing SQL statements directly on SQL Developer, it's getting executed in milliseconds.
In the spring boot, I use this to execute the statement:
Session session = sessionFactory.getCurrentSession();
session.createQuery("from Table where id = :id and status = 0").setParameter("id", id);
Here is the config properties for the database:
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
hibernate.hbm2ddl.auto=none
Here is the way of datasource initialization in the datasource config:
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(url, name, pw);
dataSource.setDriverClassName(...);
return dataSource;
}
Recently, it takes so much time to acquire the database connection, it can go up to 10 seconds jut for acquiring connection. I don't think there is any problem in the query. As from the database side, it's also ok. The resources of server which running this service and the database server are also fine, as well as the network. The servers also have auto-scale feature to create new instance when the memory getting low. I just can't figure out what should I do to improve the acquisition time. Could you please help?
I am getting this error when running my spring boot application. It is a CRUD API that I am trying to connect to my table data in SQL developer. I would really appreciate some help.
Application Properties
spring.datasource.url = jdbc:oracle:DIP:#localhost:1521:orcl
spring.datasource.username = DIP
spring.datasource.password = DIP
spring.datasource.driver-class-name = oracle.jdbc.driver.OracleDriver
server.port = 8080
Code That Generated Exception
private EmployeeDAO dao;
#BeforeEach
void setUp() throws Exception {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:oracle:DIP:#localhost:1521:orcl");
dataSource.setUsername("DIP");
dataSource.setPassword("DIP");
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dao = new EmployeeDAO(new JdbcTemplate(dataSource));
}
Oracle Driver System Path Pom.xml
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>2.3.0</version>
<scope>system</scope>
<systemPath>C:/ojdbc8.jar</systemPath>
</dependency>
The connection URL looks odd to me.
The part of the connection URL after jdbc:oracle: specifies which type of Oracle JDBC driver to use, as there's more than one of them. The only possible values this can take are thin, oci (or oci8?) and kprb (according to the Oracle JDBC driver documentation). In your code, you've set this to DIP, which appears to also be the username you are using.
I've never had any need to use kprb (in fact I didn't even know about it until today), and I haven't used oci in years. thin is the type of driver I use most often and would be the type of driver I would recommend you try to use.
Try replacing DIP in your connection URL with thin, i.e. jdbc:oracle:thin:#localhost:1521:orcl.
Note that this URL appears twice in your code, once in your properties file and once in what appears to be a test class. You will presumably need to change it in both.
I want to use jooq on a server where the DB environment is dynamic.
I want to use jooq in spring boot 2 gradle environment.
But there is a problem.
The build.gradle file requires hard-coded DB information but is available.
Can I create only JClass like QClass in QueryDSL?
I am in the server's external environment
Creates a dynamic DataSource such as ClassName, UserName, Password, and URL.
Hard-coded jooq can not be used.
In jooq
jooq{
version = '3.11.2'
sample(sourceSets.main) {
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:mysql//localhost:3306/sample'
user = 'some_user'
password = 'secret'
....
===========
The jdbc connection information should be hard-coded as shown.
But I want a dynamic jooq setting based on the external server settings.
Generally, a dynamic DataSource generation method is already in use.
Help!
I'm sorry I did not speak English.
You can build datasource in your configuration class instead of having hardcoded values in application.yml. Something like this:
#Bean
private DataSource buildDataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl(env.getProperty("dataSource.url")+ "_somevalue");
dataSource.setUsername(env.getProperty("dataSource.username"));
dataSource.setPassword(env.getProperty("dataSource.password"));
return dataSource;
}
so you can define datasource url,username,password using some logic.
I am working now with oracle and spring jdbc but I don't want to use the schema in my sql statements:
Example: Select * from SCHEMA.table
Is there any way to set default schema in application.properties or application.yml?
Assuming you define your database connections using spring datasources, you can set the default schema when defining the datasource configuration:
spring.datasource.schema = #value for your default schema to use in database
You can find more info here: Spring Boot Reference Guide. Appendix A. Common application properties
After doing some research, looks like Oracle driver doesn't let you set a default schema to work with, as noted here:
Default Schema in Oracle Connection URL
From that post, you have two options:
Execute this statement before executing your statements:
ALTER SESSION SET CURRENT_SCHEMA=yourSchema
Create synonyms for your tables/views/etc (which I find really cumbersome if we're talking about lots of elements in your database).
I would advice using the first option. From what I see, Spring boot doesn't offer a simple way to execute a statement when retrieving the connection, so the best bet will be to use an aspect around the getConnection method (or the method that retrieves the connection from the data source) and execute the statement there.
From your comment, an easier way to solve it is by using a script in spring.datasource.schema:
spring.datasource.schema = schema.sql
And then a file squema.sql with the following:
ALTER SESSION SET CURRENT_SCHEMA=mySchema
In spring boot, I've found another way of doing it,
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public DataSource dataSource(#Value("${spring.datasource.schema}") String schema) {
DataSource datasource = DataSourceBuilder.create().build();
if(!schema.isEmpty() && datasource instanceof org.apache.tomcat.jdbc.pool.DataSource){
((org.apache.tomcat.jdbc.pool.DataSource) datasource).setInitSQL("ALTER SESSION SET CURRENT_SCHEMA=" + schema);
}
return datasource;
}
I found another way to get around this by updating entity class with
#Table(schema = "SCHEMA_NAME" ,name = "TABLE_NAME")
If you are using hikari, use spring.datasource.hikari.schema=YOUR_SCHEMA.
Works for me with SpringBoot + tomcat using Oracle.
I was having issues with the currently accepted answer; specifically, the schema would only be changed from the initial connection. If your app uses a connection pool, you need to configure the pool to apply SQL for each connection.
For instance, using the default jdbc pool in Spring Boot 1.5.x (Tomcat):
spring.datasource.tomcat.init-s-q-l = ALTER SESSION SET CURRENT_SCHEMA=mySchema
Connecting to the database as your user, you can create a trigger that will change the schema each time you login:
CREATE OR REPLACE TRIGGER LOGON_TRG
AFTER LOGON ON SCHEMA
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = foo';
EXCEPTION
when others
then null;
END;
/
Another option is to create a datasource wrapper. Create the datasource as normal and then create the wrapper that forwards all methods except for the getConnection methods. For those I just added SQL to set the schema. We have multiple datasources and this allowed us to specify a different schema for each datasource. If anyone knows if there's an issue with this I'd love comments. Or if there's an alternative that uses the properties.
I'm aware that H2 has a boolean property/setting called DATABASE_TO_UPPER, which you can set at least in the connection URL, as in: ;DATABASE_TO_UPPER=false
I’d like to set this to false, but in my Spring Boot app, I don’t explicitly have a H2 connection URL anywhere. Implicitly there sure is a connection URL though, as I can see in the logs:
o.s.j.d.e.EmbeddedDatabaseFactory: Shutting down embedded database:
url='jdbc:h2:mem:2fb4805b-f927-49b3-a786-2a2cac440f44;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false'
So the question is, what's the easiest way to tell H2 to disable DATABASE_TO_UPPER in this scenario? Can I do it in code when creating the H2 datasource with EmbeddedDatabaseBuilder (see below)? Or in application properties maybe?
This is how the H2 database is explicitly initialised in code:
#Configuration
#EnableTransactionManagement
public class DataSourceConfig {
#Bean
public DataSource devDataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScripts("db/init.sql", "db/schema.sql", "db/test_data.sql")
.build();
}
}
Also, I'm telling JPA/Hibernate not to auto-generate embedded database (without this there was an issue that two in-memory databases were launched):
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=none
You can't w\ the generateUniqueName, but if you call setName("testdb;DATABASE_TO_UPPER=false") you can add parameters. I doubt this is officially supported, but it worked for me.
The spring code that generates the connection url is like this:
String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false", databaseName)
You may want abandon using explicit creation via EmbeddedDatabaseBuilder. Spring Boot creates H2 instance automatically based on configuration. So I would try this in application.properties:
spring.datasource.url=jdbc:h2:file:~/testdb;DATABASE_TO_UPPER=false