I have a search API that can abstractly search for properties of referenced entities defined in a persistence scheme. For example i have something like these entities:
@Entity
public class EntityA {
@Column
private String someProperty;
@Column
private EntityB someReference;
}
@Entity
public class EntityB {
@Column
private String someProperty;
@Column
private Set<EntityC> someReferences;
}
@Entity
public class EntityC {
@Column
private String someProperty;
}
With these entities i can traverse paths (for example when my root is EntityA and im sure that the user searches for a string field within:
private Expression<String> getExpression(Root<T> root, String fieldName) {
String[] propertySplit = fieldName.split("\\.");
Path<String> path = null;
for (String property : propertySplit) {
if (path == null) {
path = root.get(property);
continue;
}
path = path.get(property);
}
return path;
}
Assuming that is currently EntityA i can call the getExpression method like this:
[...]
criteriaBuilder.equal(getExpression(entityARoot, "someProperty"), "myValue");
[...]
And i also can invoke references:
[...]
criteriaBuilder.equal(getExpression(entityARoot, "someReference.someProperty"), "myValue");
[...]
But when the path encounters a Collection Type, then this doesn't work, but i want to do something like this:
[...]
criteriaBuilder.equal(getExpression(entityARoot, "someReference.someReferences.someProperty"), "myValue");
[...]
Im getting the following exception:
java.lang.IllegalStateException: Illegal attempt to dereference path source [null.someReferences] of basic type
I know that there must be a way to archive that since Spring Data can do that with Method-Names in Repositories too. My goal is to create a function that can traverse any unknown object as long as the final attribute i am checking is the type i know of. So i know every time whether the criteria should compare String, Integer, Boolean, Date etc.
I stumbled upon an implementation that I think is what you are looking for. Check out code for this project github.com/perplexhub/rsql-jpa-specification/ ... /RSQLJPAPredicateConverter.java#L49-L130.
I bookmarked this project as something I can import into my existing project, to enable generic handling as you have described in your question. My current implementation is hard coded against all known input predicates.