java - Spring Boot + MySQL 社区服务器

标签 java mysql spring hibernate jdbc

我一直在开发一个使用 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 语法错误相关的异常,但它并没有提供太多有关根本原因的信息。

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

  1. Test 表创建脚本与 Test Java 实体定义无关。存在不匹配,因为 test 表创建有一个名为 serviceDescription VARCHAR(40) 的字段,但在 Test java 类中有一个完全不同的属性名为 offeredServices 的名称。
  2. 创建表脚本有一个名为 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/

相关文章:

java - 至少等待 Java 执行器的一个结果而不忙等待

MySql 连接器 EF6

Java Spring Boot休息服务之争

java.sql.SQLException : Incorrect string value: '\xF3\xBE\x8D\x81' 异常

java - 如何打印对象的实现类

JAVA获取IP地址

mysql - Rails - 在文本列中插入超过 7786 个字符时获取 'Mysql server has gone away'

mysql - 动态更改选项文件中设置的数据库系统变量的值

java - 如何使用 Hibernate 处理连接

java - spring mvc中ajax调用接收json数组出错