Hibernate 命名策略更改表名
Posted
技术标签:
【中文标题】Hibernate 命名策略更改表名【英文标题】:Hibernate naming strategy changing table names 【发布时间】:2017-01-02 22:19:45 【问题描述】:我对休眠(5.1 版)命名策略有点困惑——即它改变了我的表名,我想避免这种情况。另外 - 根据 intelij,spring.jpa.hibernate.naming_strategy
似乎已被弃用,但我找不到正确配置它的(其他)方法。
我在application.properties中有如下配置:
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.mysql5Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.properties.hibernate.current_session_context_class=thread
如前所述,第一个被标记为已弃用。
现在我有了一个实体:
@Entity
@Table(name = "usaUploadTable", schema = "usertable201", catalog = "")
public class UsaUploadTable
....
表名,如@Table(name = "")
usaUploadTable。
现在当我运行我的应用程序时,我得到了
表 'usertable201.usa_upload_table' 不存在
这是正确的 - 它的名称不像 hibernate 是如何改变它的那样。
如何让 hibernate 正确使用我的表名?
编辑:
我也试过
DefaultNamingStrategy
ImprovedNamingStrategy
他们都改变了它
版本:
spring-boot-1.4.0.RELEASE
hibernate 5.1
javax-transaction-api 1.2
hibernate-validator 5.2.4
javassist 3.20
【问题讨论】:
这个 github 线程对 Hibernate 4 n 5 都很有用。 github.com/spring-projects/spring-boot/issues/2129 【参考方案1】:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
它对我有用。这是我正在使用的版本:
Spring Boot (v1.4.2.RELEASE)
Hibernate Core 5.0.11.Final
【讨论】:
【参考方案2】:问题在于 spring-boot-1.4 - 似乎他们已经更改了属性(或其他)我现在找到了这个答案ImprovedNamingStrategy no longer working in Hibernate 5,但它仍然没有正确解决。所以我稍微修改了代码,不使用下划线方法,并扩展了新引入的类SpringPhysicalNamingStrategy
:
package com.foo;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import java.io.Serializable;
import java.util.Locale;
public class RealNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable
public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
@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());
在application.properties
中,我已将弃用的行更改为
spring.jpa.properties.hibernate.physical_naming_strategy=<package>.RealNamingStrategyImpl
现在它使用的正是我在实体文件中的表名和列名。
【讨论】:
有没有办法通过 Java 配置而不是属性文件来定义NamingStrategy
?显然,这是一个很可能根本不会改变的配置。因此,我想对其进行硬编码。
黄金!这就是我一直在寻找的。两个调整 1) public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
应该是 public static final PhysicalNamingStrategyStandardImpl INSTANCE = new PhysicalNamingStrategyStandardImpl();
2) remove `import java.util.Locale;
【参考方案3】:
对于想要在 Postgresql 和 Spring boot 1.5.2 中大写的人
public class CustomDatabaseIdentifierNamingStrategy extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable
public static final long serialVersionUID = 1L;
public static final CustomDatabaseIdentifierNamingStrategy INSTANCE = new CustomDatabaseIdentifierNamingStrategy();
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context)
return new Identifier(name.getText().toUpperCase(), true);
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context)
return new Identifier(name.getText().toUpperCase(), true);
【讨论】:
在土耳其服务器上运行上述代码时要小心。toUpperCase()
会将items
转换为İTEMS
(拉丁文大写字母i,上面带有点)。要解决此问题,请始终使用toUpperCase(Locale.ROOT)
。【参考方案4】:
如果您在实体类中提供@Table 和@Column 注释,其名称带有下划线,即user_id 即@Column(name="user_id"),它将采用列名作为用户身份;如果您将其作为用户 ID 提供,那么如果您不使用策略或隐式策略(特别是 spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl),它将更改为 user_id。因此,如果您想要一个实体属性名称更改为带有下划线和小写字母的策略,即从 userId 到 user_id,您应该使用隐式或不使用策略(实际上使用隐式策略)。
如果您不希望您的命名策略在列名或类名中添加下划线,那么您需要使用的策略类似于:spring.jpa.hibernate.naming.physical-strategy=org。 hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl。您在注解 @Table 和 @Column 的 name 属性中提供的内容将保持原样。
如果您不想提供注释并想手动处理表名和列名,则应扩展类 org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 并覆盖所需的方法。如果您仍然在此处的某些情况下使用注释,请记住覆盖的方法将应用于这些注释中写入的名称。 spring.jpa.hibernate.naming.physical-strategy=example.CustomStrategy
【讨论】:
【参考方案5】:Spring 启动 2.0.0 和 Hibernate 5
public class MySqlNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment)
return false;
【讨论】:
请您详细说明您的答案如何解决 OP 问题?以上是关于Hibernate 命名策略更改表名的主要内容,如果未能解决你的问题,请参考以下文章