【问题标题】:Spring Boot + JPA : JPA seems to auto create tables but not sure whereSpring Boot + JPA:JPA 似乎会自动创建表,但不确定在哪里
【发布时间】:2021-01-14 16:38:45
【问题描述】:

我正在练习/学习一些 Spring Boot + JPA 应用程序,并在尝试保存到数据库表时遇到问题。

看起来 JPA 是自动生成表名,即使我提供了 @Table 注释。

我有一个简单的 POJO,用 @Entity 标记

@Entity
@Table(name="SongList")
public class SongList {

    @Id
    private Integer id;
    private String album;
    private String artist;
    private String title;

//Getter and Setter Methods 
}

扩展 JPA CrudRepository 的接口

import org.springframework.data.repository.CrudRepository;

public interface songRepo extends CrudRepository<SongList,Integer> {
}

设置数据源属性的属性 yml 文件

spring:
  datasource:
    driverClassName : com.mysql.cj.jdbc.Driver
    url :  jdbc:mysql://localhost:3306/Songdb
    username : root
    password : learning

jpa:
    hibernate.ddl-auto : update
    generate-ddl  : false
    show-sql : true

最后是测试类:

@SpringBootTest
@RunWith(SpringRunner.class)
class DataJpaApplicationTests {

    @Autowired
    ApplicationContext context;

    @Test
    void saveSongs() {

        songRepo repo = (songRepo) context.getBean(songRepo.class);

        SongList songs = new SongList();
        songs.setId(4);
        songs.setTitle("High Hopes");
        songs.setAlbum("Panic! At the Disco");

        repo.save(songs);

    }

}

在运行测试类时,我的测试失败并出现错误:

ERROR:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: java.sql.SQLSyntaxErrorException: Table 'songdb.song_list' doesn't exist

我的数据库表已经存在。数据库称为 Songdb(不是 songdb),表是 SongList。

我不确定表名“song_list”在哪里注入以及为什么我的数据库名称是“songdb”而不是 url 中提供的“Songdb”。

我在这里缺少什么?请帮忙!

【问题讨论】:

    标签: java spring-boot spring-data-jpa


    【解决方案1】:

    那是因为你使用的是 Spring boot 提供的默认命名策略。 Hibernate 使用物理策略和隐式策略映射字段名称。 Hibernate 使用物理命名策略将我们的逻辑名称映射到 SQL 表及其列。 Spring Boot,为这两种策略提供默认值spring.jpa.hibernate.naming.physical-strategy 默认为 org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy,和 spring.jpa.hibernate.naming.implicit-strategy 默认为 org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

    spring-boot 的默认命名策略为:

    • 用下划线替换点
    • 骆驼箱换蛇箱
    • 小写表名

    您可以通过设置如下属性来更改它:

    spring:
      jpa:
        hibernate:
          naming:
            physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
            implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    

    对于您来说,只需更改物理命名策略即可解决您的问题。您还可以使用org.hibernate.cfg.EJB3NamingStrategy,它将保留所提供的表名。既然您知道问题的原因,您可以按照自己喜欢的方式进行修复。

    您可以根据需要自定义物理命名策略,以防您需要更多控制权。阅读:Hibernate naming strategy changing table names

    【讨论】:

    • 非常感谢@Ananthapadmandabham 的详细解释!
    猜你喜欢
    • 2021-08-13
    • 2021-09-15
    • 1970-01-01
    • 2016-05-26
    • 2017-01-02
    • 1970-01-01
    • 2017-11-11
    • 2020-09-24
    • 2018-12-30
    相关资源
    最近更新 更多