根据我的Spring配置文件,Hibernate应该更新(开发)或验证(生产)db schema。但我得到了这个例外:
java.sql.SQLException: The url cannot be null
at java.sql.DriverManager.getConnection(DriverManager.java:556)
at java.sql.DriverManager.getConnection(DriverManager.java:187)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:153)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.prepare(SuppliedConnectionProviderConnectionHelper.java:51)
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:194)
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:178)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:505)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1840)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:247)
at com.example.config.MainConfig.sessionFactory(MainConfig.java:42)
at com.example.config.MainConfig$$EnhancerByCGLIB$$3cbd4ba6.CGLIB$sessionFactory$2(<generated>)
at com.example.config.MainConfig$$EnhancerByCGLIB$$3cbd4ba6$$FastClassByCGLIB$$524bdff7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)
at com.example.config.MainConfig$$EnhancerByCGLIB$$3cbd4ba6.sessionFactory(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1025)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:921)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
这是我的配置:
@Configuration
@Profile("development")
public class DevelopmentConfig {
public @Bean String profile() {
return "development";
}
}
@Configuration
@ComponentScan(basePackages = "com.example", excludeFilters = { @ComponentScan.Filter(Configuration.class) })
@PropertySource("classpath:application.properties")
@EnableTransactionManagement
public class MainConfig {
private @Autowired Environment env;
private @Autowired String profile;
public @Bean DataSource dataSource() throws IOException {
DriverManagerDataSource ret = new DriverManagerDataSource();
ret.setConnectionProperties(PropertyUtils.getProperties(profile, "jdbc"));
return ret;
}
@SuppressWarnings("deprecation") // http://stackoverflow.com/questions/14806400/configure-sessionfactory-with-spring-hibernate-and-localsessionfactorybuilder
public @Bean SessionFactory sessionFactory() throws IOException {
return new LocalSessionFactoryBuilder(dataSource())
.scanPackages("com.example.entity")
.addProperties(PropertyUtils.getProperties(profile, "hibernate"))
.buildSessionFactory();
}
public @Bean HibernateTransactionManager transactionManager() throws IOException {
return new HibernateTransactionManager(sessionFactory());
}
}
public class PropertyUtils {
private static final Logger log = LoggerFactory.getLogger(PropertyUtils.class);
public static Properties getProperties(String profile, String filename) throws IOException {
log.debug("Read " + filename + ".properties for profile " + profile);
Properties ret = new Properties();
ClassPathResource resource;
resource = new ClassPathResource("properties/common/" + filename + ".properties");
ret.putAll(PropertiesLoaderUtils.loadProperties(resource));
resource = new ClassPathResource("properties/" + profile + "/" + filename + ".properties");
if (resource.exists()) {
ret.putAll(PropertiesLoaderUtils.loadProperties(resource));
}
log.debug(ret.toString());
return ret;
}
}
First class表示要使用的配置文件(也有类似的ProductionConfig
)。
第二个类创建所有必要的东西(dataSource,sessionFactory和transactionManager)。
第三个合并公共属性和配置文件相关属性。
根据开发资料我的属性是(合并):
hibernate.properties:
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
jdbc.properties:
driverClassName=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/mydb
username=********
password=********
但是,我没有更新db模式,而是获得异常。我从未得到调试日志输出Read jdbc.properties for profile development
。所以,他们永远不会被阅读......但为什么呢?
答案 0 :(得分:0)
知道了。我认为org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.setConnectionProperties
是setDriverClassName
,setUsername
,setPassword
,setUrl
的快捷方式。它不是,我需要明确地设置所有:
public @Bean DataSource dataSource() throws IOException {
Properties jdbcProperties = PropertyUtils.getProperties(profile, "jdbc");
DriverManagerDataSource ret = new DriverManagerDataSource();
ret.setDriverClassName(jdbcProperties.getProperty("driverClassName"));
ret.setUsername(jdbcProperties.getProperty("username"));
ret.setPassword(jdbcProperties.getProperty("password"));
ret.setUrl(jdbcProperties.getProperty("url"));
return ret;
}