【问题标题】:Auto creating tables failed in Spring JPA在 Spring JPA 中自动创建表失败
【发布时间】:2013-10-09 00:40:39
【问题描述】:

我对 Spring JPA、Hibernate、MySQL 有疑问。 我有一个实体(Nom.java)和存储库(公共接口 NomRepository 扩展了 JpaRepository)。它们的创建和注入都很好。

问题是,当我尝试通过存储库的保存方法保存记录时,spring 抱怨“表不存在”。 事实上,我在 MySQL 中没有看到这个表。你尝试过 hibernate.hbm2ddl.auto 的不同值,但没有帮助。

顺便说一句,我使用无 XML 配置。

这是配置文件:

package ru.interosite.awp.config;

import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

@Configuration
@ComponentScan("ru.interosite.awp")
@EnableAutoConfiguration
public class AppConfiguration {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/awp");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setPersistenceUnitName("my_pu");
        lef.setPackagesToScan("ru.interosite.awp.data");
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setJpaProperties(getJpaProperties());
        return lef;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

        jpaVendorAdapter.setDatabase(Database.MYSQL);
        jpaVendorAdapter.setGenerateDdl(true);
        jpaVendorAdapter.setShowSql(true);
        jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");

        return jpaVendorAdapter;
    }

    private Properties getJpaProperties() {
        return new Properties() {
            {
                setProperty("hibernate.hbm2ddl.auto", "update");
                setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
                setProperty("hibernate.show_sql", "true");
                setProperty("hibernate.format_sql", "true");
            }
        };
    }
}

这是我启动应用程序的方式:

package ru.interosite.awp;

import java.awt.Font;
import javax.swing.UIManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import ru.interosite.awp.config.AppConfiguration;
import ru.interosite.awp.gui.UIUtils;

public class Boot {

    private static final Logger LOGGER = LoggerFactory.getLogger(Boot.class);

    public static void main( String[] args )
    {

        UIUtils.setUIFont(new javax.swing.plaf.FontUIResource(Font.SANS_SERIF, Font.PLAIN, 16));

        try {
            String lafClassName = UIManager.getSystemLookAndFeelClassName();
            UIManager.setLookAndFeel(lafClassName);
        } catch (Exception e) {
            LOGGER.debug(e.getMessage());
        }        

        ApplicationContext ctx = SpringApplication.run(AppConfiguration.class, args);
        ((Runner)ctx.getBean("runner")).start();
    }    
}

这是我的 pom.xml:


    4.0.0ru.interositeAWP1.0-SNAPSHOT罐子包装>

        AWPhttp://maven.apache.orgUTF-8UTF-8ru.interosite.awp.Runner属性>

        
            org.springframework.bootspring-boot-starter-parent0.5.0.M4版本>
        父>

        
            
                org.springframeworkspring-orm依赖>
            
                org.springframework.dataspring-data-jpa依赖>
            
                org.springframeworkspring-tx依赖>
            
                org.springframework.bootspring-boot-starter-data-jpa依赖>
            
                org.hibernate休眠实体管理器依赖>
            
                mysqlmysql-connector-java5.1.26版本>
            依赖>

            
                org.mockitomockito-all1.9.5版本>
            依赖>
        依赖>

        
            
                
                    maven-compiler-plugin2.3.2版本>
                插件>
                
                    org.springframework.bootspring-boot-maven-plugin插件>
            插件>
        

        
            
                弹簧快照春季快照http://repo.spring.io/libs-snapshot真启用>
                快照>
            
            
                春天的里程碑春季里程碑http://repo.spring.io/libs-milestone假启用>
                快照>
            
            
                org.jboss.repository.releasesJBoss Maven 发布存储库https://repository.jboss.org/nexus/content/repositories/releases假启用>
                快照>
            
        存储库>

        弹簧快照春季快照http://repo.spring.io/libs-snapshot真启用>
                快照>
            
            
                春天的里程碑春季里程碑http://repo.spring.io/libs-milestone假启用>
                快照>
            
        项目>

【问题讨论】:

    标签: mysql spring hibernate spring-data-jpa


    【解决方案1】:

    你需要更改两个方法并删除 getProperties() 方法:

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("com.spring.domain");
        return lef;
    }
    
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setShowSql(true);
        hibernateJpaVendorAdapter.setGenerateDdl(true); //Auto creating scheme when true
        hibernateJpaVendorAdapter.setDatabase(Database.H2);//Database type
        return hibernateJpaVendorAdapter;
    }
    

    重点是:

    hibernateJpaVendorAdapter.setGenerateDdl(true); 
    

    【讨论】:

    • 你刚刚救了一条命。
    • 成功了!非常感谢!
    【解决方案2】:

    在最新版本[spring boot]中。在application.properties中包含以下内容

    spring.jpa.generate-ddl=true
    

    【讨论】:

      【解决方案3】:

      好的,我终于找到了解决方法。 1)首先,我将 AppConfiguration 类移动到顶级包,在我的情况下为 ru.interosite.awp 2)其次,我将注释更改为:

      @Configuration
      @ComponentScan
      @EnableJpaRepositories
      public class AppConfiguration {...
      

      似乎@EnableAutoConfiguration 注释搞砸了。 我不知道这是错误还是功能。实际上看起来像是 spring-boot 的错误。

      【讨论】:

        【解决方案4】:

        我换成了 M5 spring-boot-starter-xxx jars,现在我看到我的表被创建了

        这是我的 Application 类(这是我第一次尝试 Spring Boot 所以......)

        import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType.H2;
        
        import javax.persistence.EntityManagerFactory;
        import javax.sql.DataSource;
        
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
        import org.springframework.orm.jpa.JpaTransactionManager;
        import org.springframework.orm.jpa.JpaVendorAdapter;
        import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
        import org.springframework.orm.jpa.vendor.Database;
        import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
        import org.springframework.transaction.PlatformTransactionManager;
        
        @Configuration
        @ComponentScan
        @EnableAutoConfiguration
        public class Application {
        
            public static void main(String[] args) {
                SpringApplication.run(Application.class, args);
            }
        
            @Bean
            public DataSource dataSource() {
                return new EmbeddedDatabaseBuilder().setType(H2).build();
            }
        
            @Bean
            public LocalContainerEntityManagerFactoryBean entityManagerFactory(
                    DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
                LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
                lef.setDataSource(dataSource);
                lef.setJpaVendorAdapter(jpaVendorAdapter);
                lef.setPackagesToScan("org.home.wtw.domain");
                return lef;
            }
        
            @Bean
            public JpaVendorAdapter jpaVendorAdapter() {
                HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
                hibernateJpaVendorAdapter.setShowSql(true);
                hibernateJpaVendorAdapter.setGenerateDdl(true);
                hibernateJpaVendorAdapter.setDatabase(Database.H2);
                return hibernateJpaVendorAdapter;
            }
        
            @Bean
            public PlatformTransactionManager transactionManager(
                    EntityManagerFactory entityManagerFactory) {
                return new JpaTransactionManager(entityManagerFactory);
            }
        }
        

        【讨论】:

          【解决方案5】:

          如果要创建表,必须将hibernate.hbm2ddl.auto 属性设置为create。以下是hibernate.hbm2ddl.auto 的可能值:

          • validate:验证架构,不更改数据库。
          • 更新:更新架构。
          • create:创建架构,销毁以前的数据。
          • create-drop:在会话结束时删除架构。

          另外,请检查您的数据库 url 是否正确。

          [更新]别忘了为spring定义一个事务管理器。

           @Bean
            public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor()
            {
              PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor = new PersistenceAnnotationBeanPostProcessor();
              return persistenceAnnotationBeanPostProcessor;
            }
          

          【讨论】:

          • 你是对的。如您所见,我在 getJpaProperties 方法中将 hibernate.hbm2ddl.auto 设置为“更新”。但这无济于事。
          • persistenceAnnotationBeanPostProcessor 也没有帮助。请看我的回答。
          【解决方案6】:

          尝试在 application.properties 文件中提供spring.jpa.hibernate.ddl-auto=create

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-15
            • 1970-01-01
            • 2021-09-12
            • 2021-04-01
            • 2019-03-05
            • 1970-01-01
            相关资源
            最近更新 更多