2

my Spring application has to read from a table called MY_DOMAIN_OBJECT which belongs to MY_CUSTOM_SCHEMA schema, note that the same table is present in the default schema as well.

I'm using spring-data-jdbc but I'm not able to read from the right schema. I'm creating a custom NamingStrategy bean with some method overrides but with no success, the outcome is that I get results from the table in the default schema.

Any idea of what I am doing wrong here?

Below the relevant classes:

AppConfig.java

@Configuration
@EnableJdbcRepositories(basePackages = "my.package.for.persistence")
public class AppConfig extends JdbcConfiguration {

    @Bean(name = "sourceDS", destroyMethod = "")
    public DataSource sourceDatasource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        return dataSourceLookup.getDataSource("jdbc/OracleDS");
    }

    @Bean
    public NamedParameterJdbcOperations operations() {
        return new NamedParameterJdbcTemplate(sourceDatasource());
    }

    @Bean
    //@Primary
    public NamingStrategy namingStrategy() {
        return new NamingStrategy() {

            @Override
            public String getTableName(Class<?> type) {
                return type.isAnnotationPresent(Table.class) ?
                        type.getAnnotation(Table.class).value() : NamingStrategy.super.getTableName(type);
            }

            @Override
            public String getQualifiedTableName(Class<?> type) {
                return type.isAnnotationPresent(Table.class) ?
                        type.getAnnotation(Table.class).value() : NamingStrategy.super.getTableName(type);
            }

            @Override
            public String getSchema() {
                return "my_custom_schema";
            }


        };
    }
}

MyDomainObject.java

package my.package.for.persistence;

@Data
@AllArgsConstructor
@Table("MY_DOMAIN_OBJECT")
public class MyDomainObject{

    @Id
    private Long id;

    //other fields
}

MyRepository.java

package my.package.for.persistence;

public interface MyRepository extends Repository<MyDomainObject, Long> {

    Stream<MyDomainObject> findAll();
}

UPDATE: i forgot to mention that I'm using the spring-boot-starter-data-jdbc and I suspect this is causing the issue.

vortex.alex
  • 1,105
  • 3
  • 11
  • 24
  • Which version are you using? 1.0.x or 1.1.x? I strongly recommend the later which is shortly be for a GA release. It also replaces the `JdbcConfiguration` with an `AbstractJdbcConfiguration`. If the problem still persists a github repository would be awesome to reproduce the issue. `spring-boot-starter-data-jdbc` works fine with configuring `NamingStrategy`. I did just that yesterday in a workshop. – Jens Schauder Sep 04 '19 at 13:01
  • using `1.1.0.M2` version (so without `spring-boot-starter-data-jdbc` dependency) and `AbstractJdbcConfiguration` the app fails on startup with `the bean 'jdbcMappingContext', defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [it/vortex/spring/jdbc/configuration/AppConfig.class] and overriding is disabled`. I'm not defining any bean of that type in my custom config class. – vortex.alex Sep 04 '19 at 14:19
  • @JensSchauder did you try to override also the schema in the `NamingStrategy`? – vortex.alex Sep 04 '19 at 14:22
  • No, I didn't. Do you have a github repository I could take a look at? – Jens Schauder Sep 05 '19 at 07:11
  • https://github.com/vortexalex/tutorials.git, the project is spring-boot-data-jdbc. I used an H2 db so you simply have to build and run it. What I can say is that the custom `NamingStrategy` bean gets used (you can just change the fixed table name there to another random to check that), but the `getSchema` method seems not to be called. – vortex.alex Sep 08 '19 at 10:55

1 Answers1

0

Oh sorry, I should have seen that way sooner.

Don't overwrite getQualifiedTableName the default implementation does the combining of the table and the schema name.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • thank you, I put that here just for completeness: `default String getQualifiedTableName(Class> type) { return this.getSchema() + (this.getSchema().equals("") ? "" : ".") + this.getTableName(type); }` – vortex.alex Sep 09 '19 at 07:32