1
votes

I am working on an application with Spring-starter-data-jpa and multi datasources, that need to lazy initialize datasouce connection, but i dosen't manage to work with it.

For exemple if i put a wrong password on a datasource configuration, the application startup fails.

I try to put a @Lazy annotation on the Datasource @Configuration class but the application still crash on startup.

I try to implement a LazyConnectionDataSourceProxy instead the Datasource without success.

I can't imagine that it is not possible.

Is somewone have an idea to how lazy load datasources configuration on the first jpa repository call ?

I tryed to do this with a kind of adapter/singleton mix pattern like this :

@Component
public class TestErrorDatasource implements DataSource {

private DataSource datasource;

@Autowired Environment env;

@Override
public PrintWriter getLogWriter() throws SQLException {
    return getDatasource().getLogWriter();
}

@Override
public int getLoginTimeout() throws SQLException {
    return getDatasource().getLoginTimeout();
}

@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    return getDatasource().getParentLogger();
}

@Override
public void setLogWriter(PrintWriter arg0) throws SQLException {
    getDatasource().setLogWriter(arg0);
}

@Override
public void setLoginTimeout(int arg0) throws SQLException {
    getDatasource().setLoginTimeout(arg0);
}

@Override
public boolean isWrapperFor(Class<?> arg0) throws SQLException {
    return getDatasource().isWrapperFor(arg0);
}

@Override
public <T> T unwrap(Class<T> arg0) throws SQLException {
    return getDatasource().unwrap(arg0);
}

@Override
public Connection getConnection() throws SQLException {
    return getDatasource().getConnection();
}

@Override
public Connection getConnection(String arg0, String arg1) throws SQLException {
    return getDatasource().getConnection(arg0, arg1);
}

private DataSource getDatasource() {
    if(datasource == null) {
        this.datasource = DataSourceBuilder
                .create()
                .driverClassName(env.getProperty("testError.datasource.driverClassName"))
                .url(env.getProperty("testError.datasource.url"))
                .username(env.getProperty("testError.datasource.username"))
                .password(env.getProperty("testError.datasource.password"))
                .build();
    }
    return datasource;
}

}

But it dosen't work.

I put a break point on the getConnection() methode and i raised tha it's called on startup by

org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl

class

Is there any configuration to avoid hibernate check the getConnection() methode on starup ?

Thanks in advance

1

1 Answers

0
votes

A datasource is just an interface with a 'getConnection()' method on it.

So create your own implementation that delegates to a singleton that is created only when getConnection is first called.

In other words, whilst your implementation can be a Spring bean, its singleton dependency isn't, and isn't injected, but set the first time you access getConnection.