21

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?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332

8 Answers8

22

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:

  1. Execute this statement before executing your statements:

    ALTER SESSION SET CURRENT_SCHEMA=yourSchema
    
  2. 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
Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • 1
    it doesn't work. spring.datasource.url=jdbc:oracle:thin:@server:1521:orcl spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver spring.datasource.username=joe spring.datasource.password=pepito spring.datasource.schema=SCHEMA_PA – Jose Amadeo Diaz Diaz Jun 22 '16 at 16:45
  • 1
    I configure my project using these properties: spring.datasource.url=jdbc:oracle:thin:@server:1521:orcl spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver spring.datasource.username=luchito spring.datasource.password=funca spring.datasource.schema=schema.sql and my schema.sql has alter session set current_schema=CELTIC_PA – Jose Amadeo Diaz Diaz Jun 22 '16 at 17:25
  • This doesn't work if you use a connection pool since the script is executed with just one connection while you want to execute it on all the connections. – Andrea Polci Sep 21 '18 at 07:12
  • 6
    @LuiggiMendoza I solved this by using a property specific for the connectin pool I'm using: spring.datasource.hikari.connection-init-sql=ALTER SESSION... I've seen that similar properties exists also for other connection pools – Andrea Polci Sep 24 '18 at 06:43
12

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;
} 
Deepak
  • 1,506
  • 1
  • 14
  • 13
  • This didnt work for me. Complained about missing package: org.apache.tomcat.jdbc – djangofan Oct 17 '17 at 00:08
  • 1
    There's a configuration property to set this value now: spring.datasource.tomcat.init-s-q-l – Michael R Feb 27 '18 at 22:11
  • Having the same issue. First, Hibernate was complaining that the DB connection had been closed (Connection.close()), corrected it by using testOnBorrow=true, but now this, once the first connection dies, the second one has no database schema defined, even when I used hibernate.default_schema option. Is this a bug or something? – dantebarba Sep 25 '18 at 14:59
10

If you are using hikari, use spring.datasource.hikari.schema=YOUR_SCHEMA. Works for me with SpringBoot + tomcat using Oracle.

ANooBee
  • 165
  • 1
  • 7
7

I found another way to get around this by updating entity class with

@Table(schema = "SCHEMA_NAME" ,name = "TABLE_NAME")
2

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
Michael R
  • 1,753
  • 20
  • 18
  • Worked for me! thanks! It's the esier solution for who are using Oracle... – Gustavo Amaro Apr 08 '20 at 15:43
  • @Michael R: will this property be utilized if the spring boot application is deployed on jboss as property is for tomcat? – dev_2014 Jul 29 '20 at 06:48
  • Well this answer is pretty old now and was only meant for Spring Boot 1.x applications using Tomcat JDBC Connection Pool. If you're deploying to a separate app server, it depends on how you plan to configure your JDBC connection pool. If you configure it in your app server (pretty common), you would configure this differently. I suspect that deploying a Spring Boot app as a WAR instead of using an embedded server is a pretty uncommon configuration these days. – Michael R Aug 01 '20 at 01:51
1

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;
/  
Jean de Lavarene
  • 3,461
  • 1
  • 20
  • 28
0

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.

-1
@Entity
@Table(schema = "Schema_name",  name = "table_name")
Adriaan
  • 17,741
  • 7
  • 42
  • 75
  • 1
    Please read [answer] and [edit] your answer to contain an explanation as to why this code would actually solve the problem at hand. Always remember that you're not only solving the problem, but are also educating the OP and any future readers of this post. – Adriaan Aug 14 '23 at 09:59
  • 1
    Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? **If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient.** Can you kindly [edit] your answer to offer an explanation? – Jeremy Caney Aug 15 '23 at 06:39