在Hibernate中,将列名用双引号括起来

8
我正在使用Spring JPA 2.0.9与Hibernate 5.3.5以及此方言,通过使用来自此分发的官方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,使其自动用双引号包裹所有列名称?

2个回答

20

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


10
提示:对于Spring Boot,它是 spring.jpa.properties.hibernate.globally_quoted_identifiers。对于Spring Boot来说,这个属性是 spring.jpa.properties.hibernate.globally_quoted_identifiers - Nikita Bosik

2
你可以使用hibernate.globally_quoted_identifiershibernate.keyword_auto_quoting_enabled来帮助解决问题。keyword_auto_quoting_enabled会自动为保留关键字添加引号。
但在我的情况下,我正在使用列定义。因此,Hibernate试图向数据类型添加引号。例如,在PostgreSQL中,它会尝试添加引号到"BOOLEAN""UUID"。这就是为什么我修改了物理命名策略的原因。最初的回答中提到的方法无法解决我的问题。
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属性,正是我想要的。

最初的回答:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接