【问题标题】:Why does Spring Data / Hibernate query for table "product_def" when the table is "productDef"?当表是“productDef”时,为什么 Spring Data / Hibernate 会查询表“product_def”?
【发布时间】:2021-01-23 21:53:01
【问题描述】:

我正在使用 Spring Boot 2.3.4 / Spring Data / Hibernate / MySQL 8。

我的数据库表名为“productDef”。我有一个实体对象“ProductDef”。

当我执行“列出所有”查询时,我收到此错误...

java.sql.SQLSyntaxErrorException: Table 'mydatabase.product_def' doesn't exist

Hibernate 为什么要查找表“product_def”?

我尝试向实体添加注释 @Table(name="productDef"),但这没有帮助。

如果我将 db 表重命名为“product_def”,我的代码就可以工作。但不幸的是,我无法为我的项目重命名数据库表名。

我错过了什么?

更新:

解决方案是实施自定义 PhysicalNamingStrategy 以防止“productDef”变为“product_def”。

但是,虽然这适用于 @Table 名称注释,但不适用于 @Column 名称注释。

根据to this discussion thread,忽略@Column名称注解是个bug。

将此添加到 application.properties:

spring.jpa.properties.hibernate.physical_naming_strategy=com.myapp.dao.RealNamingStrategyImpl

并像这样实现类:

package com.myapp.dao;

import java.io.Serializable;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class RealNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable {

    public static final PhysicalNamingStrategy INSTANCE = new PhysicalNamingStrategyStandardImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText(), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText(), name.isQuoted());
    }

}

【问题讨论】:

    标签: mysql spring spring-boot hibernate spring-data


    【解决方案1】:

    这是 Hibernate 使用并由 JPA 2.0 定义的默认命名策略,特别是物理命名策略:它将驼峰式大小写转换为表名和列名的下划线。

    见:https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/domain/naming.html#PhysicalNamingStrategy

    虽然ImplicitNamingStrategy 的目的是确定一个 名为accountNumber 的属性映射到逻辑列名 accountNumber 未明确指定时,a 的目的 例如,PhysicalNamingStrategy 表示物理 列名应缩写为acct_num

    有多种方法可以指定要使用的 PhysicalNamingStrategy。 首先,应用程序可以使用 hibernate.physical_naming_strategy 配置设置。

    使用 Spring,您还可以使用属性配置此策略:spring.jpa.hibernate.naming.physical-strategy

    默认情况下,Spring Boot 配置物理命名策略为 SpringPhysicalNamingStrategy。这个实现提供了相同的 表结构为 Hibernate 4:所有点都替换为下划线 骆驼外壳也被下划线取代。默认情况下,所有 表名以小写形式生成,但可以 如果您的架构需要,请覆盖该标志。

    【讨论】:

    • 谢谢!跟进问题...知道为什么 @Table(name="productDef") 不强制 Hibernate 使用表名 productDef 吗?
    • 我编辑了关于 SpringBoot 特异性的答案。如果您不希望强制执行此命名约定,则必须使用自定义策略覆盖该策略。
    • 再次感谢您的帮助...但@Table(name = "productDef") 不应该强制 Hibernate 使用该表名吗?
    • 感谢您的帮助。我通过实现自定义 SpringPhysicalNamingStrategy 让它为表名工作......但现在我在列名方面遇到了同样的问题......经过一番挖掘后,似乎有一个错误导致 @Column 注释被忽略。此处讨论主题:github.com/spring-projects/spring-boot/issues/2129
    • 嗨——仅供参考,我在这里发布了一个关于我的“忽略的@Column”注释的后续问题。请看一下! stackoverflow.com/questions/64271945/…
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 2014-09-15
    • 1970-01-01
    相关资源
    最近更新 更多