首页 > 解决方案 > 为什么 Spring Data JPA 不插入名称以大写字符开头的表中?它会自动转换为情人并得到错误

问题描述

我正在开发一个尝试使用Spring Data JPAHibernate的 Spring Boot 应用程序,但我发现尝试将新记录插入示例表时遇到了一些困难。

这是我的应用程序pom.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.easydefi</groupId>
    <artifactId>GET-USER-WS</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>GET-USER-WS</name>
    <description>Microservice that retrieves users from DB</description>
    <properties>
        <java.version>11</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>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <!-- JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

这是我的application.properties文件内容:

spring.datasource.url = jdbc:postgresql://172.21.0.2:5432/EasyDefiDB
spring.datasource.username = postgres
spring.datasource.password = MY_PSWD
spring.datasource.driver-class-name = org.postgresql.Driver
spring.jpa.hibernate.ddl-auto = none
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

然后在我的 Postgres 中,我创建了一个名为EasyDefiDB的数据库,其中包含我用来执行一些实验的非常简单的示例表:

CREATE TABLE IF NOT EXISTS public."Example"
(
    id bigint NOT NULL,
    test character varying(50) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT "Example_pkey" PRIMARY KEY (id)
)

所以我创建了这个Example实体类:

package com.easydefi.users.entity;

import java.io.Serializable;
import java.util.Date;

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

import lombok.Data;

@Entity
@Table(name = "Example")
@Data
public class Example implements Serializable {

    private static final long serialVersionUID = -2878723722630662986L;
    
    @Id
    @Column(name = "id")
    private int id;
    
    @Column(name = "test")
    private String test;
    
    

    public Example(String test) {
        super();
        this.test = test;
    }



    public Example() {
        super();
    }
    

}

然后我创建了这个扩展JpaRepository接口的ExampleRepository

public interface ExampleRepository extends JpaRepository<Example, Integer> {

}

目前这个接口是空的,因为我只是想使用 JpaRepository save()方法保存一条新记录。

最后我创建了这个单元测试类来测试保存行为:

@SpringBootTest()
@ContextConfiguration(classes = GetUserWsApplication.class)
@TestMethodOrder(OrderAnnotation.class)
public class ExampleRepositoryTest {
    
    @Autowired
    private ExampleRepository exampleRepository;
    
    @Test
    @Order(1)
    public void TestInsertExample()
    {
        Example example = new Example("TEST");
        
        exampleRepository.save(example);
        
        assertTrue(true);
        
    }

}

问题是运行这个方法,当调用save()方法时,它在我的堆栈跟踪中给我以下错误:

2021-11-03 17:10:59.059  INFO 15054 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-11-03 17:10:59.416  WARN 15054 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-11-03 17:11:00.453  INFO 15054 --- [           main] c.e.users.GetUserWsApplicationTests      : Started GetUserWsApplicationTests in 5.067 seconds (JVM running for 6.686)
2021-11-03 17:11:00.812  INFO 15054 --- [           main] o.s.t.c.support.AbstractContextLoader    : Could not detect default resource locations for test class [com.easydefi.users.tests.RepositoryTests.ExampleRepositoryTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2021-11-03 17:11:00.818  INFO 15054 --- [           main] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
2021-11-03 17:11:00.818  INFO 15054 --- [           main] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@703eead0, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@674fd531, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@7f53b345, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@76ee7301, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@71817f66, org.springframework.test.context.support.DirtiesContextTestExecutionListener@68feca3a, org.springframework.test.context.transaction.TransactionalTestExecutionListener@ad585fb, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@fa689db, org.springframework.test.context.event.EventPublishingTestExecutionListener@75a6bd06, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@6b170692, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@4d4bac56, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@76980c75, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@3696d12d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@656672fb, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@75df4b1d]
Hibernate: 
    insert 
    into
        example
        (test, id) 
    values
        (?, ?)
2021-11-03 17:11:09.867  WARN 15054 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42P01
2021-11-03 17:11:09.869 ERROR 15054 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: relation "example" does not exist
  Position: 13

所以基本上问题似乎是,由于某种我无法理解的原因,它试图插入示例表而不是示例(正如它在我的数据库中定义的那样,第一个大写字符)。

将我的表从Example重命名为example它工作正常,新记录正确插入到该表中。

但为什么?如何更改此行为以允许我正确插入以大写字母开头的表格?

标签: javaspringspring-boothibernatespring-data-jpa

解决方案


推荐阅读