使用Hibernate和Spring Boot时出现问题。 Hibernate加载两次,所以它创建了DB,然后再次重新创建它(使用hbm2ddl.auto = create,所以我希望一次)。
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = {
UserMapper.class,
EventMapper.class,
GroupMapper.class,
UserServiceImpl.class,
EventServiceImpl.class,
GroupServiceImpl.class,
UserController.class
})
@PropertySource(value = {"classpath:application.properties"})
@Import({ DatabaseConfig.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
和DatabaseConfig:
@EnableJpaRepositories(basePackageClasses = {
EventRepository.class,
GroupRepository.class,
UserRepository.class
})
@EnableTransactionManagement
public class DatabaseConfig {
private static final String DB_DRIVER_CLASS = "db.driver";
private static final String DB_PASSWORD = "db.password";
private static final String DB_URL = "db.url";
private static final String DB_USERNAME = "db.username";
private static final String DB_SSL = "db.ssl";
private static final String DB_SSL_FACTORY = "db.ssl.factory";
private static final String DB_FORMAT_SQL = "db.formatSql";
private static final String DB_DIALECT = "db.dialect";
private static final String DB_SHOW_SQL = "db.show_sql";
private static final String DB_HBM2DLL_AUTO = "db.hbm2ddl.auto";
private static final String DB_POOL_SIZE = "db.poolSize";
@Resource
private Environment env;
@Bean
public SessionFactory sessionFactory() throws IOException {
final LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(packagesToScan());
factory.setHibernateProperties(dataSourceProperties());
factory.setAnnotatedClasses(classesToAdd());
factory.afterPropertiesSet();
return factory.getObject();
}
private DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(DB_DRIVER_CLASS));
dataSource.setUrl(env.getRequiredProperty(DB_URL));
dataSource.setUsername(env.getRequiredProperty(DB_USERNAME));
dataSource.setPassword(env.getRequiredProperty(DB_PASSWORD));
dataSource.setConnectionProperties(connectionPropertiesDev());
return dataSource;
}
public Class[] classesToAdd() {
return new Class[]{
};
}
public String[] packagesToScan() {
return new String[] {""};
}
private Properties dataSourceProperties() {
Properties props = new Properties();
props.put("hibernate.connection.driver_class", env.getRequiredProperty(DB_DRIVER_CLASS));
props.put("hibernate.connection.url", env.getRequiredProperty(DB_URL));
props.put("hibernate.connection.username", env.getRequiredProperty(DB_USERNAME));
props.put("hibernate.connection.password", env.getRequiredProperty(DB_PASSWORD));
props.put("hibernate.connection.pool_size", env.getRequiredProperty(DB_POOL_SIZE));
props.put("hibernate.connection.requireSSL", env.getRequiredProperty(DB_SSL));
props.put("hibernate.hbm2ddl.auto", env.getRequiredProperty(DB_HBM2DLL_AUTO));
props.put("hibernate.show_sql", env.getRequiredProperty(DB_SHOW_SQL));
props.put("hibernate.dialect", env.getRequiredProperty(DB_DIALECT));
props.put("hibernate.format_sql", env.getRequiredProperty(DB_FORMAT_SQL));
return props;
}
private Properties connectionPropertiesDev() {
Properties properties = new Properties();
properties.put("ssl", env.getRequiredProperty(DB_SSL, Boolean.class));
properties.put("sslfactory", env.getRequiredProperty(DB_SSL_FACTORY));
return new Properties();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(packagesToScan());
entityManagerFactoryBean.setJpaProperties(dataSourceProperties());
return entityManagerFactoryBean;
}
@Bean
public HibernateTransactionManager transactionManager() throws IOException {
final HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory());
txManager.afterPropertiesSet();
return txManager;
}
}
有谁知道为什么会这样?
答案 0 :(得分:1)
对于其他可能和我一样的错误,Dave Syer的回答是正确的。 我检查了http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#appendix并阅读了整个文档。
只需提供正确的配置值,您将获得很长的路要走。感谢Dave的帮助。
答案 1 :(得分:1)
检查您的web.xml文件,确保没有加载spring ApplicationContext两次。确保contextConfigurationLocation和appServlet不是同一个文件。如果是,那么您的应用程序上下文将被加载两次。我在这些线条周围有星号。我正在使用调度程序,因为我在这些位置有相同的文件,计划的任务运行了两次。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>FLEX Contacts Mobile Service</display-name>
<context-param>
***<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>***
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
**<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet-context.xml</param-value>**
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/flex_contacts_mobile_service/*</url-pattern>
</servlet-mapping>
</web-app>