My fork of airsonic with experimental fixes and improvements. See branch "custom"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
airsonic-custom/airsonic-main/src/main/java/org/airsonic/player/spring/DatabaseConfiguration.java

109 lines
4.1 KiB

package org.airsonic.player.spring;
import org.airsonic.player.dao.DaoHelper;
import org.airsonic.player.dao.GenericDaoHelper;
import org.airsonic.player.dao.LegacyHsqlDaoHelper;
import org.airsonic.player.service.SettingsService;
import org.airsonic.player.util.Util;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Avoid exceptions if database is not ready and fully migrated on first startup In particular, this should fix an issue described in #884 (and reproduced since), where Airsonic tries to access the database while Liquibase has not finished running all the migrations. 2020-01-07 23:00:26.697 ERROR --- o.a.p.service.PodcastService : Failed to initialize PodcastService: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:230) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:654) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:688) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:720) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:730) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:780) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.AbstractDao.query(AbstractDao.java:93) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao.getAllChannels(PodcastDao.java:73) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao$$FastClassBySpringCGLIB$$9fcd2715.invoke(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.PodcastDao$$EnhancerBySpringCGLIB$$b59c1dc5.getAllChannels(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.getAllChannels(PodcastService.java:185) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.init(PodcastService.java:112) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1622) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:211) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:300) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:135) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.airsonic.player.Application.main(Application.java:207) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) ~[airsonic.war:10.6.0-SNAPSHOT] Caused by: java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.hsqldb.jdbc.Util.throwError(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1525) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] ... 61 common frames omitted
5 years ago
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
@Profile("legacy")
Avoid exceptions if database is not ready and fully migrated on first startup In particular, this should fix an issue described in #884 (and reproduced since), where Airsonic tries to access the database while Liquibase has not finished running all the migrations. 2020-01-07 23:00:26.697 ERROR --- o.a.p.service.PodcastService : Failed to initialize PodcastService: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:230) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:654) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:688) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:720) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:730) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:780) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.AbstractDao.query(AbstractDao.java:93) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao.getAllChannels(PodcastDao.java:73) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao$$FastClassBySpringCGLIB$$9fcd2715.invoke(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.PodcastDao$$EnhancerBySpringCGLIB$$b59c1dc5.getAllChannels(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.getAllChannels(PodcastService.java:185) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.init(PodcastService.java:112) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1622) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:211) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:300) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:135) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.airsonic.player.Application.main(Application.java:207) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) ~[airsonic.war:10.6.0-SNAPSHOT] Caused by: java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.hsqldb.jdbc.Util.throwError(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1525) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] ... 61 common frames omitted
5 years ago
@DependsOn("liquibase")
public DaoHelper legacyDaoHelper(DataSource dataSource) {
return new LegacyHsqlDaoHelper(dataSource);
}
@Bean
@ConditionalOnMissingBean
Avoid exceptions if database is not ready and fully migrated on first startup In particular, this should fix an issue described in #884 (and reproduced since), where Airsonic tries to access the database while Liquibase has not finished running all the migrations. 2020-01-07 23:00:26.697 ERROR --- o.a.p.service.PodcastService : Failed to initialize PodcastService: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select id, url, title, description, image_url, status, error_message from podcast_channel]; nested exception is java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:230) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:654) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:688) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:720) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:730) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:780) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.AbstractDao.query(AbstractDao.java:93) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao.getAllChannels(PodcastDao.java:73) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.dao.PodcastDao$$FastClassBySpringCGLIB$$9fcd2715.invoke(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671) ~[spring-aop-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.airsonic.player.dao.PodcastDao$$EnhancerBySpringCGLIB$$b59c1dc5.getAllChannels(<generated>) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.getAllChannels(PodcastService.java:185) ~[classes!/:10.6.0-SNAPSHOT] at org.airsonic.player.service.PodcastService.init(PodcastService.java:112) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1622) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:211) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) ~[spring-beans-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:300) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:135) ~[spring-boot-1.5.22.RELEASE.jar!/:1.5.22.RELEASE] at org.airsonic.player.Application.main(Application.java:207) ~[classes!/:10.6.0-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[airsonic.war:10.6.0-SNAPSHOT] at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) ~[airsonic.war:10.6.0-SNAPSHOT] Caused by: java.sql.SQLException: Table not found in statement [select id, url, title, description, image_url, status, error_message from podcast_channel] at org.hsqldb.jdbc.Util.throwError(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source) ~[hsqldb-1.8.0.7.jar!/:private-2006/09/24-10:30:15] at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1525) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632) ~[spring-jdbc-4.3.25.RELEASE.jar!/:4.3.25.RELEASE] ... 61 common frames omitted
5 years ago
@DependsOn("liquibase")
public DaoHelper daoHelper(DataSource dataSource) {
return new GenericDaoHelper(dataSource);
}
@Bean
@Profile("legacy")
public DataSource legacyDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl(SettingsService.getDefaultJDBCUrl());
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
@Bean
@Profile("embed")
public DataSource embedDataSource(@Value("${DatabaseConfigEmbedDriver}") String driver,
@Value("${DatabaseConfigEmbedUrl}") String url,
@Value("${DatabaseConfigEmbedUsername}") String username,
@Value("${DatabaseConfigEmbedPassword}") String password) {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(driver);
basicDataSource.setUrl(url);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
return basicDataSource;
}
@Bean
@Profile("jndi")
public DataSource jndiDataSource(@Value("${DatabaseConfigJNDIName}") String jndiName) {
JndiDataSourceLookup jndiLookup = new JndiDataSourceLookup();
return jndiLookup.getDataSource(jndiName);
}
@Bean
public File rollbackFile() {
return new File(SettingsService.getAirsonicHome(), "rollback.sql");
}
@Bean
public String userTableQuote(@Value("${DatabaseUsertableQuote:}") String value) {
return value;
}
@Bean
public SpringLiquibase liquibase(DataSource dataSource,
@Value("${DatabaseMysqlMaxlength:512}")
String mysqlVarcharLimit,
String userTableQuote) {
SpringLiquibase springLiquibase = new SpringLiquibase();
springLiquibase.setDataSource(dataSource);
springLiquibase.setChangeLog("classpath:liquibase/db-changelog.xml");
springLiquibase.setRollbackFile(rollbackFile());
Map<String, String> parameters = new HashMap<>();
parameters.put("defaultMusicFolder", Util.getDefaultMusicFolder());
parameters.put("mysqlVarcharLimit", mysqlVarcharLimit);
parameters.put("userTableQuote", userTableQuote);
springLiquibase.setChangeLogParameters(parameters);
return springLiquibase;
}
}