【发布时间】:2017-08-03 15:20:56
【问题描述】:
我试图在加载应用程序期间通过 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
【问题讨论】:
-
任何提示?真的很感激
-
我已经编辑了代码。我需要更改或修复什么?
-
更新您的数据库并将
USER表中的ID设为AUTO INCREMENT。 -
Abdullah Khan,数据库是由 Hibernate 创建的。您可以看到所有字段都已注释。 GenerationType.AUTO 正在执行 AUTO INCREMENT,对吗?如果我错了,请纠正我。有没有其他方法可以使 id 自动递增,而不是手动递增?
-
GenerationType.AUTO本身不会为您创建数据库和 ID。 hibernate 属性hbm2ddl为您完成了这项工作。
标签: hibernate spring-mvc spring-data-jpa