在 Hibernate 中将列名用双引号引起来
Wrap column names in double quotes in Hibernate
我正在使用 Spring JPA 2.0.9 与 Hibernate 5.3.5 和 this dialect to access a FileMaker (v16) database via JDBC using the official JDBC driver taken from this distribution。
问题是,结果 SQL 最终会以相应的 table 名称为前缀的列名称,例如:
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): There is
an error in the syntax of the query.
然而,如果列名像这样用双引号括起来,它会毫无怨言地吞下 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,使其自动将所有列名称用双引号引起来?
您可以在定义中设置一个名为 hibernate.globally_quoted_identifiers
到 true
的 属性,它将引用所有标识符。除此之外还有一个不引用列的选项,但是没有只引用列的选项。
您可以使用 hibernate.globally_quoted_identifiers
或 hibernate.keyword_auto_quoting_enabled
可能会有帮助。 keyword_auto_quoting_enabled
为保留关键字自动添加引号。
但就我而言,我使用的是列定义。所以 hibernates 试图为数据类型添加引号。例如 postgresql 中的 "BOOLEAN"
或 "UUID"
。这就是我修改物理命名策略的原因。
hibernate.naming.physical-strategy = com.mypackage.MyCustomPhysicalNamingStrategyImpl
这里是示例命名策略 class。
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 不会修改列定义,但会保留 table 和列名。
示例实体:
@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
属性 这正是我想要的。
我正在使用 Spring JPA 2.0.9 与 Hibernate 5.3.5 和 this dialect to access a FileMaker (v16) database via JDBC using the official JDBC driver taken from this distribution。
问题是,结果 SQL 最终会以相应的 table 名称为前缀的列名称,例如:
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): There is an error in the syntax of the query.
然而,如果列名像这样用双引号括起来,它会毫无怨言地吞下 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,使其自动将所有列名称用双引号引起来?
您可以在定义中设置一个名为 hibernate.globally_quoted_identifiers
到 true
的 属性,它将引用所有标识符。除此之外还有一个不引用列的选项,但是没有只引用列的选项。
您可以使用 hibernate.globally_quoted_identifiers
或 hibernate.keyword_auto_quoting_enabled
可能会有帮助。 keyword_auto_quoting_enabled
为保留关键字自动添加引号。
但就我而言,我使用的是列定义。所以 hibernates 试图为数据类型添加引号。例如 postgresql 中的 "BOOLEAN"
或 "UUID"
。这就是我修改物理命名策略的原因。
hibernate.naming.physical-strategy = com.mypackage.MyCustomPhysicalNamingStrategyImpl
这里是示例命名策略 class。
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 不会修改列定义,但会保留 table 和列名。
示例实体:
@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
属性 这正是我想要的。