Cyrusmith
Cyrusmith

Reputation: 757

Auto creating tables failed in Spring JPA

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

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.

I use XML-less configuration 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:

 
<?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>

Upvotes: 8

Views: 33432

Answers (6)

Vito
Vito

Reputation: 1090

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

@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); 

Upvotes: 15

jeeva nantham
jeeva nantham

Reputation: 853

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

Upvotes: 0

Kris Swat
Kris Swat

Reputation: 1016

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

spring.jpa.generate-ddl=true

Upvotes: 6

Phillip Williams
Phillip Williams

Reputation: 41

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

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

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

Upvotes: 2

Cyrusmith
Cyrusmith

Reputation: 757

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:

@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.

Upvotes: 3

Dimitri
Dimitri

Reputation: 8290

If you want the tables to be created, you must set hibernate.hbm2ddl.auto property to create. Here are the possible values for 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.

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

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

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

Upvotes: 1

Related Questions