AuditQuery and relationships


#1

Hello,

Can relations be queried in the current version (5.x)? For example, would this work:

query.traverseRelation("Child", JoinType.LEFT, "ChildAlias")
					.add(AuditEntity.property("ChildAlias", "name").like(some-value));

Also, not sure if ‘Child’ in this case is the relationship name (in the master Entity), or the child entity name?

Thanks!


#2

I suppose you are talking about Envers. Check out the User Guide for many query examples related to Envers.


#3

Yes, i was not specific enough. This is what I found in the docs you sent the link for:

“The main limitation of the current queries implementation is that you cannot traverse relations. You can only specify constraints on the ids of the related entities, and only on the “owning” side of the relation. This, however, will be changed in future releases.”

BTW, the last sentence was there in version 3.* …


#4

Cam anyone suggest a workaround? I just need to query for the One side properties in a ManyToOne relationship?


#5

Maybe @Naros can help you with that.


#6

Thanks Vlad!
I am not sure, however, how to send a question to a member of this forum directly?


#7

Hi @gbakalar!

In Hibernate Envers 5.x, the only traversal that is currently supported are those that are to-one mappings. We intend to support the to-many association traversal in Hibernate Envers 6.0.

That said, lets assume we have the following mappings:

@Entity
@Audited
public class Parent {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  @OneToMany(mappedBy = "parent")
  private List<Child> children; 
}

@Entity
@Audited
public class Child {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  @ManyToOne
  private Parent parent;
}

We want to find all the revisions of Child where it has the name C1 and has a Parent with the name P1.

List results = auditReader.createQuery()
    .forRevisionsOfEntity( Child.class, true, false )
    .traverseRelation( "parent", JoinType.INNER )
     // Apply prdicate on the `Parent` entity.
    .add( AuditEntity.property( "name" ).eq( "P1" ) )
    .up()
     // Apply predicate on the `Child` entity.
    .add( AuditEntity.property( "name" ).eq( "C1" ) )
    .getResultList();

As you can see from my example, the first argument to traverseRelation is the property name of the attribute you want to traverse relative to the current class as part of the context. In other words, I am saying that we want to traverse the parent property that is in the Child class and then filter on a property in Parent called name with the value of P1.

Hopefully that clears up any confusion.


#8

Thank you very much! This is exactly what I need. To have functional dependencies under control, that is definitely great first step. One thing - how do i query for transitively dependent objects? For example:

Child->Parent->GrandParent

Would this work?
List results = auditReader.createQuery()
.forRevisionsOfEntity( Child.class, true, false )
.traverseRelation( “parent”, JoinType.INNER )
.traverseRelation( “grand-parent”, JoinType.INNER )
.add( AuditEntity.property( “gp-name” ).eq( “GP1” ) )
.up()

Would this work?


#9

Forgot to ask one more thing - I assume i should be able to set the order to properties that belong to Parent. Is this correct?
Thanks!


#10

@Naros I am getting exception: “… not yet implemented …”. In what exact version is your example supported?

Thanks!


#11

java.lang.UnsupportedOperationException: Not yet implemented for revisions of entity queries
I am using envers version 5.4.1


#12

@Naros - I apologize, but this is urgent and i am not sure if what I need is really supported in 5.4.1?


#13

This is how the implementation looks like:
@Override
public AuditAssociationQuery<? extends AuditQuery> traverseRelation(String associationName, JoinType joinType) {
throw new UnsupportedOperationException( “Not yet implemented for revisions of entity queries” );
}

When you wrote your example, you must have had certain implementation in mind - certainly not the one in 5.4.1 - right?


#14

Yes, so long as the relation is a to-one, you can simply traverse the object-graph as nested as you need and apply the appropriate predicates to filter the results.

I’m not clear on what you’re asking here.

My apologies, you’re correct the RevisionsOfEntityQuery does not yet support this feature; I simply wrote an example to illustrate the syntax and overlooked that. The other two query implementations should work, EntitiesModifiedAtRevisionQuery and EntitiesAtRevisionQuery.

I assume you need to be able to fetch a list of revisions based on predicates rather than knowing the revision numbers ahead of time?


#15

About the order - I need to sort on a property of ‘toOne’ entity.
About the query - Yes, I need a list of revisions filtered by a property of ‘toOne’ entity.

Do you have any idea when will this be available? I would even take ‘code in development’, as long as it can be used for couple of scenarios I need! (that’s how desperate i am :slight_smile:


#16

@Naros - Any hint here?