SqlException使用数据库populator与Hibernate和Spring数据JPA

时间:2017-08-03 15:20:57

标签: hibernate spring-mvc spring-data-jpa

我正在尝试在加载应用程序期间通过DatabasePopulator将数据存储到mysql数据库中。我正在使用Spring MVC,Hibernate和Spring Data JPA。但是我得到了一些SqlException错误。我一直试图通过Hibernate提供的更改ID生成策略来修复它,但没有成功。 提前致谢。也许需要在我的域对象对象中更改某些内容。如果我手动填充代码一切正常。但是,通过使用DataPopulator会遇到错误。

域对象

 package springmvc.java.domain;

    import java.util.List;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;

    @Entity
    @Table(name = "user")
    public class User {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        // @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", unique = true, nullable = false)
        private Long id;

        @Column(name = "username", nullable = false)
        private String username;

        @Column(name = "password")
        private String password;

        @Column(name = "enabled", nullable = false)
        private boolean enabled;

        // @ElementCollection
        @OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
        private List<BlogPost> blogPosts;

        public User() {

        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }

        public List<BlogPost> getBlogPosts() {
            return blogPosts;
        }

        public void setBlogPosts(List<BlogPost> blogPosts) {
            this.blogPosts = blogPosts;
        }

    }




    package springmvc.java.domain;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


    @Entity
    @Table(name = "blog_post")
    public class BlogPost {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id", unique = true, nullable = false)
        private Long id;

        @Column(name = "title", nullable = false)
        private String title;

        @Column(name = "content", nullable = false)
        private String content;

        // @Column(name = "publishDate", nullable = false)
        @Column(name = "publishDate", nullable = true)
        private Date publishDate;

        @Column(name = "draft", nullable = false)
        private boolean draft;

    //  @JsonIgnore
        @ManyToOne
        @JoinColumn(name = "user_id", nullable = false)
        private User user;

        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public Date getPublishDate() {
            return publishDate;
        }

        public void setPublishDate(Date publishDate) {
            this.publishDate = publishDate;
        }

        public boolean isDraft() {
            return draft;
        }

        public void setDraft(boolean draft) {
            this.draft = draft;
        }

    }




package springmvc.java.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

    @Entity
    @Table(name = "authorities")
    public class Authority {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "", unique = true, nullable = false)
        private Long id;

        @Column(name = "username", nullable = false)
        private String username;

        @Column(name = "authority", nullable = false)
        private String authority;

        public Authority() {

        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getAuthority() {
            return authority;
        }

        public void setAuthority(String authority) {
            this.authority = authority;
        }

    }




package springmvc.java.config;

@EnableJpaRepositories(basePackages = { "springmvc.java.dao" })
@EnableTransactionManagement
@Configuration
@ComponentScan("springmvc.java")
public class ApplicationContext {


    private DatabasePopulator databasePopulator() {

        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        databasePopulator.setContinueOnError(false);
        databasePopulator.addScript(new ClassPathResource("/test-insert-data.sql"));

        return databasePopulator;
    }



    /*
     * Second Configuration Option
     * 
     */
    @Bean
    public DataSource getMySQLDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/blog?useSSl=false");
        dataSource.setUsername("root");
        dataSource.setPassword("root");

        return dataSource;
    }



    @Bean
    public BlogPostService blogPostService() {
        return new BlogPostServiceImpl();
    }


    @Bean
    public JpaVendorAdapter getJpaVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setDatabase(Database.MYSQL);
        jpaVendorAdapter.setShowSql(true);

        return jpaVendorAdapter;
    }

    /*
     * Hibernate Configuration
     */
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();

        entityManagerFactory.setDataSource(getMySQLDataSource());

        entityManagerFactory.setJpaVendorAdapter(getJpaVendorAdapter());

        entityManagerFactory.setPackagesToScan("springmvc.java.domain");

        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");

        entityManagerFactory.setJpaProperties(jpaProperties);

        return entityManagerFactory;
    }

    /*
     * TransactionManager Configuration
     */
    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);

        // The exception is thrown here
        DatabasePopulatorUtils.execute(databasePopulator(), getMySQLDataSource());

        return jpaTransactionManager;
    }
}

返回

错误:

    ERROR ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in springmvc.java.config.ApplicationContext: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaTransactionManager]: Factory method 'transactionManager' threw exception; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [test-insert-data.sql]: INSERT INTO USER(USERNAME, PASSWORD, ENABLED) VALUES('user','password', TRUE); nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4725) [catalina.jar:na]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5189) [catalina.jar:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:na]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752) [catalina.jar:na]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728) [catalina.jar:na]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) [catalina.jar:na]
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596) [catalina.jar:8.5.9-dev]
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805) [catalina.jar:8.5.9-dev]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [na:1.8.0_144]
    at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_144]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_144]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaTransactionManager]: Factory method 'transactionManager' threw exception; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [test-insert-data.sql]: INSERT INTO USER(USERNAME, PASSWORD, ENABLED) VALUES('user','password', TRUE); nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    ... 27 common frames omitted
Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [test-insert-data.sql]: INSERT INTO USER(USERNAME, PASSWORD, ENABLED) VALUES('user','password', TRUE); nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:491) ~[spring-jdbc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:238) ~[spring-jdbc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48) ~[spring-jdbc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at springmvc.java.config.ApplicationContext.transactionManager(ApplicationContext.java:186) ~[classes/:na]
    at springmvc.java.config.ApplicationContext$$EnhancerBySpringCGLIB$$75c8c2da.CGLIB$transactionManager$2(<generated>) ~[classes/:na]
    at springmvc.java.config.ApplicationContext$$EnhancerBySpringCGLIB$$75c8c2da$$FastClassBySpringCGLIB$$9644c818.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at springmvc.java.config.ApplicationContext$$EnhancerBySpringCGLIB$$75c8c2da.transactionManager(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    ... 28 common frames omitted
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2490) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2448) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:470) ~[spring-jdbc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    ... 41 common frames omitted

2 个答案:

答案 0 :(得分:0)

错误很明确:/usr/include/apache2/http_log.h:372:18: note: expected 'apr_status_t {aka int}' but argument is of type 'server_rec * {aka struct server_rec *}' AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index, ^ apxs:Error: Command failed with rc=65536

实际上,您正尝试使用SQL脚本填充数据库。由于您的脚本是通过与数据源的连接直接执行的,因此Hibernate不会用于生成id列。

您需要在SQL脚本中添加id的值才能使其正常工作。或者您必须使用Hibernate填充数据库。在您的情况下,这意味着您可以使用Spring Data来完成工作。

答案 1 :(得分:0)

可能存在许多失败的可能性,有时可能无法反映任何实体修改。您应该手动删除并重新创建数据库,或者创建新模式并导出现有模式。

除此之外,您还可以使用hibernate import_files属性来加载sql脚本:

hibernate.hbm2ddl.import_files=location_of_sqlfiles_comma_saperated_string'. These statements are only executed if the schema is created ie if hibernate.hbm2ddl.auto is set to create or create-drop.

另一个原因是生成类型:

看看GeneratedValue的策略。它通常看起来像:

@GeneratedValue(strategy=GenerationType.IDENTITY).

您应该使用数据库初始化,如下所示:

@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
    final DataSourceInitializer initializer = new DataSourceInitializer();
    initializer.setDataSource(dataSource);
    initializer.setDatabasePopulator(databasePopulator());
    return initializer;
}

private DatabasePopulator databasePopulator() {
    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.addScript(schemaScript);
    populator.addScript(dataScript);
    return populator;
}

确保使用auto_increament check

创建数据库表