假设我们有一个实体:
@Entity
@Audited(withModifiedFlag = true)
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, length = 50)
private String Name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentEntityId")
private MyEntity parentEntity;
}
我尝试使 envers 返回表示关系的实体字段的实体修订信息。我用addProjection
创建我自己的数据表示。问题是每次我使用 addProjection
代表关系的字段名称我遇到错误(如果我使用普通列则不会出现错误)。
我构建了一个审核查询:
AuditQuery auditQuery = reader.createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true);
auditQuery.addProjection(AuditEntity.revisionNumber());
auditQuery.addProjection(AuditEntity.revisionType());
auditQuery.addProjection(AuditEntity.revisionProperty("timestamp"));
auditQuery.addProjection(AuditEntity.id());
auditQuery.addProjection(new AuditProperty<>(
new EntityPropertyName("parentEntity")));
auditQuery.addProjection(new AuditProperty<>(
new ModifiedFlagPropertyName(
new EntityPropertyName("parentEntity"))));
错误是:
org.hibernate.QueryException: could not resolve property: parentEntity of: edu.sample.domain.entity.MyEntity_AUD
我还尝试过:new EntityPropertyName("parentEntityId")
- 结果是:
org.hibernate.QueryException: could not resolve property: parentEntityId of: edu.sample.domain.entity.MyEntity_AUD
编辑:
我错过了审计查询中的一条语句。投影应包括parentEntity字段值,而不仅仅是修改后的标志:
auditQuery.addProjection(new AuditProperty<>(
new EntityPropertyName("parentEntity")));
我需要该字段的值以及该字段是否被修改的信息。这就是为什么我使用 withModifiedFlag = true
问题在于 MyEntity_AUD 表(自动生成)的架构包含字段 parentEntityId
。修改后的标志字段名称为parentEntity_MOD
。将以下投影添加到查询后会出现错误:
-
addProjection(new AuditProperty<>( new EntityPropertyName("parentEntity")));
或
-
addProjection(new AuditProperty<>( new EntityPropertyName("parentEntityId")));
修改标志正确返回,没有错误。以及普通字段的值。
最佳答案
如果您确实想在此处使用投影,您可以使用 selectEntity
来完成此操作选项。您在此处查找的语法如下:
AuditQuery query = reader.createQuery()
.forRevisionsOfEntity( MyEntity.class, false, true );
query.addProjection( AuditEntity.revisionNumber() );
query.addProjection( AuditEntity.revisionType() );
query.addProjection( AuditEntity.revisionProperty( "timestamp" ) );
query.addProjection( AuditEntity.selectEntity( false ) );
您现在应该能够使用返回的对象数组中的特定条目来访问该版本中的任何关联或属性。但请注意,这与使用以下语法没有太大不同:
List results = reader.createQuery()
.forRevisionsOfEntity( MyEntity.class, false, true )
.getResultList();
for ( Object row : results ) {
final Object[] array = (Object[]) row;
final MyEntity entity = (MyEntity) array[0];
final Object revisionEntity = array[1];
final RevisionType revisionType = (RevisionType) array[2];
}
这里唯一需要注意的是 revisionEntity
可以是 Envers 公开的任意数量的实现,也可以是您自己的自定义实现,具体取决于您如何配置环境。您必须检查正在使用哪个并进行相应的转换。
两者是同义词并且产生相同的结果。
唯一真正的区别是前者将实体返回为 Map<String,Object>
其中-as 后者返回实际的水合实体实例。
关于java - 无法将投影添加到 envers 查询中的关系字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44987493/