0

I have a data source that is setup & then, used by a third party software to execute sql. After the sql is run I have another bean that executes & closes the connection.

@Bean
public DataSource datasource() {
    HikariConfig myconfig = new HikariConfig();
    ...
    return new HikariDataSource(myconfig);
}

@Bean
@DependsOn("sqlproject")
public void closeConnection() throws SQLException {
    Connection c = datasource().getConnection();
    try {
        c.close();
    } 
    finally {
        System.out.println(c.isClosed());
    }
}

However, I can clearly still make local calls using that datasource connection to particular data. Should I not be calling datasource() because this creates a new instance ? What am I doing wrong ?

duppydodah
  • 165
  • 1
  • 3
  • 17

1 Answers1

0

You're right, when you're calling datasource from configuration class, new instance is created because Spring AOP doesn't support self invocation via this.

Moreover, even if you have used this AOP correctly, this wouldn't have closed DataSource, since you're creating new connection (via getConnection() and then closing it.

If you want to close HikariDataSource, then you need to call HikariDataSource#close.

Also, you don't need @Bean annotation on your void method since it makes no sense.

geobreze
  • 2,274
  • 1
  • 10
  • 15
  • Would I need to call `HikariDataSource#close` within the same `datasource()` method ? How else would you close it without creating a new instance ? Also, strangely enough the `closeConnection()` method is not called when it does not have the `@Bean` annotation; I had the same thinking. – duppydodah Nov 23 '21 at 17:00
  • When do you need this method to be called? – geobreze Nov 23 '21 at 17:08
  • I need it to be called after the "sqlproject" library completes its execution; which won't happen until the DataSource is already setup. I know for a fact that `closeConnection()` is always called afterwards which is why I was trying to use it. Would a `DriverManager#getConnection` be of use ? – duppydodah Nov 23 '21 at 17:12
  • 1
    If you need to call something after something completes, you need to use `@PreDestroy` annotation, `DisposableBean` interface or you can listen to `ContextRefreshedEvent` (https://www.baeldung.com/spring-events) and perform code you want depending on `ApplicationContext` state – geobreze Nov 23 '21 at 17:19
  • I thought `@PreDestroy` was for executing something in the very start of deletion process ? So, I would need a `DisposableBean` & then, create its own `destroy()` method I suppose. – duppydodah Nov 23 '21 at 17:26
  • `@PreDestroy` is pretty the same as `DisposableBean` it's called when a bean reaches the end of life – geobreze Nov 23 '21 at 17:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239506/discussion-between-user3696953-and-geobreze). – duppydodah Nov 23 '21 at 19:05