使用未知对象结构的条件根元素遍历路径

Traverse Path with Criteria Root element of unkown object structure

我有一个搜索 API 可以抽象地搜索在持久性方案中定义的引用实体的属性。 例如,我有类似这些实体的东西:

@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;
}

使用这些实体我可以遍历路径(例如,当我的根是 EntityA 并且我确定用户在以下范围内搜索字符串字段时:

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;
    }

假设当前是 EntityA,我可以这样调用 getExpression 方法:

[...]
criteriaBuilder.equal(getExpression(entityARoot, "someProperty"), "myValue");
[...]

而且我还可以调用引用:

[...]
criteriaBuilder.equal(getExpression(entityARoot, "someReference.someProperty"), "myValue");
[...]

但是当路径遇到集合类型时,这就不起作用了,但我想做这样的事情:

[...]
criteriaBuilder.equal(getExpression(entityARoot, "someReference.someReferences.someProperty"), "myValue");
[...]

我收到以下异常:

java.lang.IllegalStateException: Illegal attempt to dereference path source [null.someReferences] of basic type

我知道必须有一种方法来存档,因为 Spring 数据也可以通过存储库中的方法名称来实现。 我的目标是创建一个可以遍历任何未知对象的函数,只要我检查的最终属性是我知道的类型即可。所以我每次都知道标准是否应该比较字符串、整数、布尔值、日期等

如果您想要立即访问(即在您的查询中),则需要急切地获取嵌套实体的集合。

    @OneToMany(fetch = FetchType.EAGER) 
    @Column
    private Set<EntityC> someReferences;

注意“someReference.someProperty”等不是空安全的,如果“someReference”为空,您将得到意想不到的结果。建议像上面的评论一样弄清楚如何使用 Join 以避免这种情况。

我偶然发现了一个我认为是您正在寻找的实现。查看此项目的代码 github.com/perplexhub/rsql-jpa-specification/ ... /RSQLJPAPredicateConverter.java#L49-L130.

我将这个项目添加为书签,作为我可以导入到我现有项目中的东西,以启用您在问题中描述的通用处理。我当前的实现是针对所有已知的输入谓词进行硬编码的。