1

I have a Spring application that's trying to connect to a database. In order to connect, an SSH tunnel must first be established (using Jsch). How do I delay HibernateJpaAutoConfiguration until after the bean that's establishing the Jsch SSH session has returned? Currently the application is failing to start because the tunnel hasn't been opened yet. When I try to exclude this autoconfiguration class, and then instantiate it explicitly predicated on the session bean already having been created, I get the following error:

Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!

I don't understand why I suddenly have to provide this myself when, if I rely on the auto-configuration, I don't have to provide it. If someone can show me a way to achieve this, that would be great.

POM:

        ...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- Spring data JPA, default tomcat pool, exclude it -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jdbc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        ...

Main application:

@SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class)
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }

    @Configuration
    static class SshTunnelConfiguration {
        @Bean
        public com.jcraft.jsch.Session sshTunnel() {
            ...
        }
    }

    @Configuration
    @ConditionalOnBean(com.jcraft.jsch.Session.class)
    static class DelayedJpaConfiguration extends HibernateJpaAutoConfiguration {
        public JpaConfiguration(DataSource dataSource, JpaProperties jpaProperties, ObjectProvider<JtaTransactionManager> jtaTransactionManager, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
            super(dataSource, jpaProperties, jtaTransactionManager, transactionManagerCustomizers);
        }
    }
}
Ben R.
  • 1,965
  • 1
  • 13
  • 23
  • 1
    Have you tried adding auto-configuration of your own with `@AutoConfigureBefore`? – chrylis -cautiouslyoptimistic- Nov 06 '20 at 15:12
  • Because your `DelayedJpaConfiguration` overrides the default auto-configuration effectively disabling all of it so no more auto-configuration. Also the only thing you probably have to wait for the datasource and not for the full JPA configuration to run. – M. Deinum Nov 06 '20 at 15:34

1 Answers1

0

You would have to implement your own data source (by extending the one you use) and implementing the InitializingBean interface and in the 'afterPropertiesSet' method initialize your jsch tunnel.

Please refer to this: Spring Data JPA with ssh tunnel to a remote MySQL server

mrkurtan
  • 573
  • 2
  • 13