Envers 查询对 _MOD 列使用了错误的列名
Envers queries use wrong column names for _MOD columns
我将 Hibernate Envers 与 @Audited( withModifiedFlag=true )
一起使用,我遇到了一个问题,即为查询生成的 SQL 的列名与 HBM2DDL
工具生成的列名不同_MOD
列
这个问题可能与我重写 here 中描述的 Hibernate 命名策略有关。但是试图调试这个,我没有运气来验证这个理论——命名策略似乎没有遇到任何断点。
实体看起来像这样(省略了不相关的属性):
@Entity
@Table(name = "file")
@Audited(withModifiedFlag = true)
public class FileEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "file_name")
private String fileName;
}
生成的 _AUD
table 看起来像这样:
CREATE TABLE file_AUD (
id int8 NOT NULL,
REV int4 NOT NULL,
REVTYPE int2,
REVEND int4,
file_name varchar(255),
fileName_MOD boolean,
PRIMARY KEY (id, REV)
);
我可以看到 file_name
和 fileName_MOD
列之间的区别,但这似乎是预期的,如 here
所述
更改实体或使用 AuditReaderFactory
进行查询时,显示以下 SQL 错误:
ERROR: column fileentity0_.file_name_mod does not exist
Hint: Perhaps you meant to reference the column "fileentity0_.filename_mod".
我正在使用 PostgreSQL 和 Hibernate 5.2.13.Final
我知道在每个 属性 上使用 modifiedColumnName
是一种解决方法,但上面的示例只是我尝试审核的众多实体之一,因此我正在寻找其他解决方案。
编辑:
深入研究 NamingStrategy,似乎代码实际上并未使用我添加的自定义代码。似乎 Hibernate naming_strategy
属性 被拆分为 implicit_naming_strategy
和 physical_naming_strategy
并且随着项目中 Hibernate 版本的更新,这似乎没有引起注意。
相反,这些属性由 Spring JPA 默认提供,如下所示:
hibernate.implicit_naming_strategy:org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
hibernate.physical_naming_strategy:org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
因为他们完成了这项工作(在这个 Envers 问题之外),我不会使用自定义的。
我使用的查询示例:
AuditReader auditReader = AuditReaderFactory.get(entityManager);
AuditQuery auditQuery = auditReader.createQuery()
.forRevisionsOfEntity(FileEntity.class, false, true)
.addOrder(AuditEntity.revisionNumber().desc())
.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize());
理想的解决方案是扩展 spring-boot
实现并检查标识符是否以 _MOD
后缀结尾,如果是,则使其 return 具有相同的标识符而不更改它。然后配置 spring-boot
以使用自定义命名策略,无需重命名列即可正常工作。
我将 Hibernate Envers 与 @Audited( withModifiedFlag=true )
一起使用,我遇到了一个问题,即为查询生成的 SQL 的列名与 HBM2DDL
工具生成的列名不同_MOD
列
这个问题可能与我重写 here 中描述的 Hibernate 命名策略有关。但是试图调试这个,我没有运气来验证这个理论——命名策略似乎没有遇到任何断点。
实体看起来像这样(省略了不相关的属性):
@Entity
@Table(name = "file")
@Audited(withModifiedFlag = true)
public class FileEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "file_name")
private String fileName;
}
生成的 _AUD
table 看起来像这样:
CREATE TABLE file_AUD (
id int8 NOT NULL,
REV int4 NOT NULL,
REVTYPE int2,
REVEND int4,
file_name varchar(255),
fileName_MOD boolean,
PRIMARY KEY (id, REV)
);
我可以看到 file_name
和 fileName_MOD
列之间的区别,但这似乎是预期的,如 here
更改实体或使用 AuditReaderFactory
进行查询时,显示以下 SQL 错误:
ERROR: column fileentity0_.file_name_mod does not exist
Hint: Perhaps you meant to reference the column "fileentity0_.filename_mod".
我正在使用 PostgreSQL 和 Hibernate 5.2.13.Final
我知道在每个 属性 上使用 modifiedColumnName
是一种解决方法,但上面的示例只是我尝试审核的众多实体之一,因此我正在寻找其他解决方案。
编辑:
深入研究 NamingStrategy,似乎代码实际上并未使用我添加的自定义代码。似乎 Hibernate naming_strategy
属性 被拆分为 implicit_naming_strategy
和 physical_naming_strategy
并且随着项目中 Hibernate 版本的更新,这似乎没有引起注意。
相反,这些属性由 Spring JPA 默认提供,如下所示:
hibernate.implicit_naming_strategy:org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
hibernate.physical_naming_strategy:org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
因为他们完成了这项工作(在这个 Envers 问题之外),我不会使用自定义的。
我使用的查询示例:
AuditReader auditReader = AuditReaderFactory.get(entityManager);
AuditQuery auditQuery = auditReader.createQuery()
.forRevisionsOfEntity(FileEntity.class, false, true)
.addOrder(AuditEntity.revisionNumber().desc())
.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize());
理想的解决方案是扩展 spring-boot
实现并检查标识符是否以 _MOD
后缀结尾,如果是,则使其 return 具有相同的标识符而不更改它。然后配置 spring-boot
以使用自定义命名策略,无需重命名列即可正常工作。