有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法将投影添加到envers查询中的关系字段

假设我们有一个实体:

@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一起使用表示关系的字段名时,我都会遇到一个错误(如果使用oridinary column,则不会出现错误)

我构建了一个审计查询:

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表(自动生成)的模式包含字段^{。修改后的标志字段名为parentEntity_MOD。将以下投影添加到查询后,错误会显示:

  • addProjection(new AuditProperty<>( new EntityPropertyName("parentEntity")));

或者

  • addProjection(new AuditProperty<>( new EntityPropertyName("parentEntityId")));

修改标志正确返回,没有错误。以及普通字段的值


共 (1) 个答案

  1. # 1 楼答案

    如果你真的想在这里使用投影,你可以使用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>,后者返回实际的水合实体实例