【问题标题】:Wrap column names in double quotes in Hibernate在 Hibernate 中将列名用双引号括起来
【发布时间】:2018-09-14 09:24:10
【问题描述】:

我正在使用 Spring JPA 2.0.9 和 Hibernate 5.3.5 和 this dialect 使用来自 distribution 的官方 JDBC 驱动程序通过 JDBC 访问 FileMaker (v16) 数据库。

问题是生成的 SQL 最终以列名为前缀,并以相应的表名为前缀,例如:

select 
marketingc0_.a__IDPK_MarketingCategory as a__IDPK_1_0_0_, marketingc0_.Active as Active2_0_0_
from MarketingCategories as marketingc0_
where marketingc0_.a__IDPK_MarketingCategory=1

哪个 FileMaker 不接受抱怨语法错误:

[08007][27034] [FileMaker][FileMaker JDBC] FQL0001/(1:153):有 查询语法错误。

但是,如果列名用这样的双引号括起来,它会毫无怨言地吞下 SQL:

select
    marketingc0_."a__IDPK_MarketingCategory" as a__IDPK_1_0_0_, marketingc0_."Active" as Active2_0_0_
    from MarketingCategories as marketingc0_
    where marketingc0_.a__IDPK_MarketingCategory=1

我想出的解决方案是将这些引号包含到实体注释中:

public class MarketingCategory {
    @Id
    @Column(name = "\"a__IDPK_MarketingCategory\"")
    private Integer id;

    @Column(name = "\"a_ID_User\"")
    private Integer userId;

    @Column(name = "\"Active\"")
    private Boolean active;

...
}

看起来不太好。

是否可以将 Hibernate 配置为自动将所有列名用双引号括起来?

【问题讨论】:

    标签: java hibernate spring-data-jpa filemaker


    【解决方案1】:

    您可以在定义中将名为hibernate.globally_quoted_identifiers 的属性设置为true,它将引用所有标识符。除了不引用列之外,还有一个选项,但没有仅引用列的选项。

    【讨论】:

    • 提示:对于 Spring Boot,它是 spring.jpa.properties.hibernate.globally_quoted_identifiers
    【解决方案2】:

    您可以使用hibernate.globally_quoted_identifiershibernate.keyword_auto_quoting_enabled 可能会有所帮助。 keyword_auto_quoting_enabled 为保留关键字自动添加引号。

    但就我而言,我使用的是列定义。所以hibernates试图在数据类型中添加引号。例如 "BOOLEAN""UUID" 在 postgresql 中。这就是我修改物理命名策略的原因。

    hibernate.naming.physical-strategy = com.mypackage.MyCustomPhysicalNamingStrategyImpl
    

    这里是示例命名策略类。

    public class MyCustomPhysicalNamingStrategyImpl implements PhysicalNamingStrategy, Serializable {
    
        public static final MyCustomPhysicalNamingStrategyImpl INSTANCE = new MyCustomPhysicalNamingStrategyImpl();
    
        @Override
        public Identifier toPhysicalCatalogName(final Identifier name, final JdbcEnvironment context) {
    
            return new Identifier(name.getText(), true);
        }
    
        @Override
        public Identifier toPhysicalSchemaName(final Identifier name, final JdbcEnvironment context) {
    
            return new Identifier(name.getText(), true);
        }
    
        @Override
        public Identifier toPhysicalTableName(final Identifier name, final JdbcEnvironment context) {
    
            return new Identifier(name.getText(), true);
        }
    
        @Override
        public Identifier toPhysicalSequenceName(final Identifier name, final JdbcEnvironment context) {
    
            return new Identifier(name.getText(), true);
        }
    
        @Override
        public Identifier toPhysicalColumnName(final Identifier name, final JdbcEnvironment context) {
    
            return new Identifier(name.getText(), true);
        }
    }
    

    Hibernate 不会修改列定义,而是保持表和列名不变。

    示例实体:

    @Data
    @Entity
    @Table(name = "CHAT")
    public class Chat {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ID", nullable = false)
        private long id;
    
        @Column(name = "UUID", columnDefinition = "UUID", nullable = false, length = 16)
        private UUID uuid;
    
        @Column(name = "NAME", length = 16)
        private String name;
    }
    

    命名将保持原样:

    CHAT
    ------------
    ID
    UUID
    NAME
    

    更新:Hibernate 5.2 具有 GLOBALLY_QUOTED_IDENTIFIERS_SKIP_COLUMN_DEFINITIONS 属性,这正是我想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 2019-10-26
      相关资源
      最近更新 更多