mysql - 当表是 "product_def"时,为什么 Spring Data/Hibernate 查询表 "productDef"?

标签 mysql spring spring-boot hibernate spring-data

我正在使用 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"),但这没有帮助。

如果我将数据库表重命名为“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());
    }

}

最佳答案

这是 Hibernate 使用的默认命名策略,由 JPA 2.0 定义,具体来说,是physicalNamingStrategy:它将表名和列名的驼峰式大小写转换为下划线。

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

While the purpose of an ImplicitNamingStrategy is to determine that an attribute named accountNumber maps to a logical column name of accountNumber when not explicitly specified, the purpose of a PhysicalNamingStrategy would be, for example, to say that the physical column name should instead be abbreviated acct_num.

There are multiple ways to specify the PhysicalNamingStrategy to use. First, applications can specify the implementation using the hibernate.physical_naming_strategy configuration setting.

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

By default, Spring Boot configures the physical naming strategy with SpringPhysicalNamingStrategy. This implementation provides the same table structure as Hibernate 4: all dots are replaced by underscores and camel casing is replaced by underscores as well. By default, all table names are generated in lower case, but it is possible to override that flag if your schema requires it.

关于mysql - 当表是 "product_def"时,为什么 Spring Data/Hibernate 查询表 "productDef"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64269485/

相关文章:

java - 如何创建 Spring Boot 中外部 jar 上存在的类的对象?

java - Spring 启动: Update Operation in New Thread

php - 从数据库中检索数据并统计数据出现的次数

spring - 使用 Spring Cloud FeignClients 时出现 404

mysql - 如何在mysql中配置Saiku的维度

java - Spring:为什么用@PostConstruct 注释的方法不能是静态的?

java - 部署 Spring Boot Fat jar

spring-boot - 在 WebSecurityConfigurerAdapter 类被弃用后,authenticationManagerBean 函数的替代方法是什么?

mysql - Django ORM : Tried to do inner join with foreign key but causes FieldError

mysql - 我的查询在 mysql 中工作,但不适用于 laravel eloquent