Spring启动+ MySQL社区服务器

时间:2017-08-05 06:50:00

标签: java mysql spring hibernate jdbc

我一直致力于使用Spring boot + MySQL社区服务器作为数据库的应用程序。

我的问题是,如果我使用像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

data.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');

来自我在java的课程:

@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

从我的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

1 个答案:

答案 0 :(得分:1)

SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

SQLGrammarException是与sql语法错误相关的异常,但它没有提供有关根本原因的大量信息。

我试图使用相同的属性名称和表名复制相同的错误,我发现了这个:

  1. Test表创建脚本与Test Java实体定义无关。存在不匹配,因为test表创建了一个名为serviceDescription VARCHAR(40)的字段,但在Test java类中有一个名为offeredServices的完全不同的属性名称。
  2. create table脚本有一个名为name VARCHAR(40)的字段,但在Test Java实体定义中没有name属性。
  3. 现在让我们假设我们有两个与数据库表和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;
        }
    }
    

    data.sql

    INSERT INTO test(name, offeredServices) VALUES
      ('Test 1','Test 1'),
      ('Test 2','Test 2');
    

    测试库

        public interface TestRepository extends JpaRepository<Test,Integer> {}
    

    Spring Boot Class

    @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属性名称(从camelCase)转换为offered_services列名称(转换为SNAKE_CASE),因为hibernate正在使用SpringNamingStrategy生成表名和列名。

    要解决此问题,只需在@Column(name="offeredservices")属性中添加offeredServices注释即可。 @Column(name="offeredservices")注释告诉hibernate不要尝试将camelCase属性名转换为SNAKE_CASE,只需将列名保留为小写。

    这是Test java class的最终版本。

    @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