MySQL Spring JPA 中的自动创建表失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19140163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 19:02:05  来源:igfitidea点击:

Auto creating tables failed in Spring JPA

mysqlspringhibernatespring-data-jpa

提问by Cyrusmith

I have an issue with Spring JPA, Hibernate, MySQL. I have an Entity (Nom.java) and repository (public interface NomRepository extends JpaRepository). They are created and injected just fine.

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

The issue is that when I'm trying to save a record via repository's save method spring complaines that "Table '' doesn't exist". Indeed I do not see this table in MySQL. U've tried different values of hibernate.hbm2ddl.auto but it did not help.

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

I use XML-less configuration BTW.

我使用无 XML 配置 BTW。

Here's the config file:

这是配置文件:

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");
            }
        };
    }
}

Here's how I start the app:

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

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();
    }    
}

This is my pom.xml:

这是我的 pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <项目 xmlns="http://maven.apache.org/POM/4.0.0" 
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>

        <groupId>ru.interosite</groupId>
        <artifactId>AWP</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>

        <name>AWP</name>
        <url>http://maven.apache.org</url>

        <属性>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <start-class>ru.interosite.awp.Runner</start-class>
        </属性>

        <父>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <版本>0.5.0.M4</version>
        </父>

        <依赖>
            <依赖>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
            </依赖>
            <依赖>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-jpa</artifactId>
            </依赖>
            <依赖>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
            </依赖>                    
            <依赖>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </依赖>        
            <依赖>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
            </依赖>
            <依赖>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <版本>5.1.26</version>
            </依赖>

            <依赖>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
                <版本>1.9.5</version>
            </依赖>                                        
        </依赖>

        <构建>
            <插件>
                <插件> 
                    <artifactId>maven-compiler-plugin</artifactId> 
                    <version>2.3.2</version> 
                </插件>
                <插件>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </插件>
            </插件>
        </build>

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

        <插件库>
            <插件库>
                <id>弹簧快照</id>
                <name>春季快照</name>
                <url>http://repo.spring.io/libs-snapshot</url>
                <快照>
                    <已启用>真</已启用>
                </快照>
            </pluginRepository>
            <插件库>
                <id>春天的里程碑</id>
                <name>春季里程碑</name>
                <url>http://repo.spring.io/libs-milestone</url>
                <快照>
                    <已启用>假</已启用>
                </快照>
            </pluginRepository>
        </pluginRepositories>        

    </项目>

采纳答案by Cyrusmith

Ok, finally I have found how to fix it. 1) First, I moved AppConfiguration class to top-level package, ru.interosite.awp in my case 2) Second, I changed annotations to be:

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

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

Seems that @EnableAutoConfiguration annotation messed things up. I dunno if it is a bug or feature. Looks like a bug of spring-boot actually.

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

回答by Vito

you need to chang two method and delete getProperties() method:

您需要更改两个方法并删除 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;
}

the point is:

重点是:

hibernateJpaVendorAdapter.setGenerateDdl(true); 

回答by Kris Swat

In the latest version [spring boot].Include the below in application.properties

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

spring.jpa.generate-ddl=true

回答by Phillip Williams

I swapped to the M5 spring-boot-starter-xxx jars and now I'm seeing my tables get created

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

Here's my Application class (this is my first attempt at spring boot so...)

这是我的应用程序类(这是我第一次尝试 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);
    }
}

回答by Dimitri

If you want the tables to be created, you must set hibernate.hbm2ddl.autoproperty to create. Here are the possible values for hibernate.hbm2ddl.auto:

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

  • validate: validate the schema, makes no changes to the database.
  • update: update the schema.
  • create: creates the schema, destroying previous data.
  • create-drop: drop the schema at the end of the session.
  • 验证:验证架构,不对数据库进行任何更改。
  • 更新:更新架构。
  • create:创建模式,销毁以前的数据。
  • create-drop:在会话结束时删除模式。

Also, check that you are your database url is correct.

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

[Update]And don't forget to define a transaction manager for spring.

[更新]并且不要忘记为spring定义一个事务管理器。

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

回答by jeeva nantham

Trying giving spring.jpa.hibernate.ddl-auto=createin application.properties file.

尝试spring.jpa.hibernate.ddl-auto=create在 application.properties 文件中给出。