在Spring JPA中自动创建表失败

oxosxuxt  于 2023-03-16  发布在  Spring
关注(0)|答案(6)|浏览(138)

我在Spring JPA、Hibernate、MySQL上遇到了一个问题。我有一个实体(NomIdejava)和存储库(公共接口NomRepository扩展了JpaRepository〈Nom,String〉)。它们的创建和注入都很好。
问题是当我试图通过存储库的save方法保存一个记录时,spring抱怨“Table "不存在”。事实上,我在MySQL中看不到这个表。你已经尝试了www.example.com的不同值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:

<?xml version="1.0" encoding="UTF-8"?>
<project
    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>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <start-class>ru.interosite.awp.Runner</start-class>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>0.5.0.M4</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.26</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>org.jboss.repository.releases</id>
            <name>JBoss Maven Release Repository</name>
            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
k0pti3hp

k0pti3hp1#

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

bvn4nwqk2#

最新版本[ Spring Boot ]。请将以下内容包含在www.example.com中application.properties

spring.jpa.generate-ddl=true
slsn1g29

slsn1g293#

好了,我终于找到了修复方法。1)首先,我将AppConfiguration类移到顶层包,在我的例子中为ru.interosite.awp。2)其次,我将注解更改为:

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

看起来@EnableAutoConfiguration注解把事情搞砸了。我不知道这是一个bug还是特性。实际上看起来像是Spring启动的bug。

nafvub8i

nafvub8i4#

我切换到M5 spring-boot-starter-xxx jar,现在我看到我的表已创建
这是我的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);
    }
}
q8l4jmvw

q8l4jmvw5#

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

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

此外,检查您是您的数据库网址是正确的.
[Update]不要忘记为spring定义一个事务管理器。

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

8qgya5xd6#

尝试在www.example.com文件中提供spring.jpa.hibernate.ddl-auto=createapplication.properties。

相关问题