【问题标题】:Hibernate naming strategy changing table namesHibernate 命名策略更改表名
【发布时间】: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

【问题讨论】:

标签: java mysql spring hibernate jpa


【解决方案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 问题?
      猜你喜欢
      • 2023-03-21
      • 2019-04-16
      • 2016-01-11
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      相关资源
      最近更新 更多