我一直在开发一个使用 Spring boot + MySQL Community Server 作为数据库的应用程序。
我的问题是,如果我使用像 offeredServices
这样的复合名称,我的浏览器会出现此错误:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Aug 04 21:15:23 EEST 2017
There was an unexpected error (type=Internal Server Error, status=500).
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
数据.sql
INSERT INTO test(name, offeredServices) VALUES
('Test 1','Test 1'),
('Test 2','Test 2');
DROP DATABASE IF EXISTS v;
CREATE DATABASE v;
USE v;
CREATE TABLE test (
id INT PRIMARY KEY auto_increment,
name VARCHAR(40),
serviceDescription VARCHAR(40)
);
但如果我使用像 nnnn
这样的短/简单名称,它就可以工作
DROP DATABASE IF EXISTS v;
CREATE DATABASE v;
USE v;
CREATE TABLE test (
id INT PRIMARY KEY auto_increment,
name VARCHAR(40),
nnnn VARCHAR(40)
);
INSERT INTO test(name, nnnn) VALUES
('Test 1','Test 1'),
('Test 2','Test 2');
来 self 的 java 类(class):
@Entity
@Table(name = "test")
public class Test {
private int id;
private String nnnn;
public String getNnnn() {
return nnnn;
}
public void setNnnn(String nnnn) {
this.nnnn = nnnn;}
@Entity
@Table(name = "test")
public class Test {
private int id;
private String offeredServices;
public String getOfferedServices() {
return offeredServices;
}
public void setOfferedServices(String offeredServices) {
this.offeredServices = offeredServices;}
我的 application.properties。
spring.datasource.url=jdbc:mysql://localhost:3306/v?autoReconnect=true&useSSL=false
spring.datasource.username=junior
spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
server.port=8089
来 self 的 pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
我不太了解:
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
因为它忽略了我的初始值。
使用 spring.jpa.hibernate.ddl-auto=update
会出现以下错误。
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-05 10:26:32.951 ERROR 6528 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at com.example.EmployeeLocatorApplication.main(EmployeeLocatorApplication.java:10) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) ~[spring-orm-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) ~[spring-orm-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 16 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to execute schema management to JDBC target [create table project (id integer not null auto_increment, name varchar(255), team_id integer not null, primary key (id)) ENGINE=InnoDB]
at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:59) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:431) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:420) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.createTable(SchemaMigratorImpl.java:236) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:167) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:60) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:134) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:101) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:472) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
... 22 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'project' already exists
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_131]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_131]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1540) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2595) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1468) ~[mysql-connector-java-5.1.41.jar:5.1.41]
at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:56) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
... 32 common frames omitted
------------------------------------------------------------------------
BUILD FAILURE
------------------------------------------------------------------------
Total time: 9.998s
Finished at: Sat Aug 05 10:26:33 EEST 2017
Final Memory: 10M/155M
------------------------------------------------------------------------
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (default-cli) on project my-project: Command execution failed. Process exited with an error: 1 (Exit value: 1) -> [Help 1]
To see the full stack trace of the errors, re-run Maven with the -e switch.
Re-run Maven using the -X switch to enable full debug logging.
For more information about the errors and possible solutions, please read the following articles:
[Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
最佳答案
SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
SQLGrammarException
是与 sql 语法错误相关的异常,但它并没有提供太多有关根本原因的信息。
我试图使用相同的属性名称和表名称来复制相同的错误,我发现了这一点:
Test
表创建脚本与Test
Java 实体定义无关。存在不匹配,因为test
表创建有一个名为serviceDescription VARCHAR(40)
的字段,但在Test
java 类中有一个完全不同的属性名为offeredServices
的名称。- 创建表脚本有一个名为
name VARCHAR(40)
的字段,但在Test
Java 实体定义中没有name
属性。
现在假设我们有两个与数据库表和 Java 实体类相关的组件。 像这样
创建测试表
DROP DATABASE IF EXISTS v;
CREATE DATABASE v CHARACTER SET utf8 COLLATE utf8_bin;
USE v;
CREATE TABLE test (
id INT PRIMARY KEY auto_increment,
name VARCHAR(40),
offeredServices VARCHAR(40)
);
测试java类
@Entity
@Table(name = "test")
public class Test {
@Id
@GeneratedValue
private int id;
private String name;
private String offeredServices;
public String getOfferedServices() {
return offeredServices;
}
public void setOfferedServices(String offeredServices) {
this.offeredServices = offeredServices;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
数据.sql
INSERT INTO test(name, offeredServices) VALUES
('Test 1','Test 1'),
('Test 2','Test 2');
测试库
public interface TestRepository extends JpaRepository<Test,Integer> {}
Spring Boot 类
@SpringBootApplication
public class MysqlerrordemoApplication {
public static void main(String[] args) {
SpringApplication.run(MysqlerrordemoApplication.class, args);
}
@Bean
public CommandLineRunner runner( TestRepository testRepository){
return (args) -> {
testRepository.findAll().forEach(System.out::println);
};
}
}
当我运行应用程序时出现以下错误:
SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test0_.service_description' in 'field list'
此异常意味着 hibernate 正在将 offeredServices
属性名称(从驼峰命名法)转换为 offered_services
列名称(到 SNAKE_CASE),因为 hibernate 正在使用 SpringNamingStrategy
生成表名和列名。
要解决此问题,只需将 @Column(name="offeredservices")
注释添加到 offeredServices
属性即可。 @Column(name="offeredservices")
注释告诉 hibernate 不要尝试将 camelCase 属性名称转换为 SNAKE_CASE,只需将列名称保持小写即可。
这是 Test java 类的最终版本。
@Entity
@Table(name = "test")
public class Test {
@Id
@GeneratedValue
private int id;
private String name;
@Column(name="offeredservices")
private String offeredServices;
public String getOfferedServices() {
return offeredServices;
}
public void setOfferedServices(String offeredServices) {
this.offeredServices = offeredServices;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
要获得有关此问题的非常明确的答案,请转到此帖子 spring-boot-jpa-column-name-annotation-ignored
请同时保留 spring.jpa.hibernate.ddl-auto 属性为 create-drop
spring.jpa.hibernate.ddl-auto=create-drop
关于java - Spring Boot + MySQL 社区服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45519145/