Can we build Spring Data JPA specification out of a composite key attribute

纵饮孤独 提交于 2021-02-07 18:12:29

问题


I am using Spring Data JPA specifications for generic queries to my entities. So far it has worked well. Now the problem happened when I try to use these on composite keys used via embeddedId annotation. So here I need to use a nested property to query which say if the object is Foo and I am trying to write a criteria over id. id1 for example.

@Entity
@Data
public class Foo implements Serializable {
    private static final long serialVersionUID = 1L;
     /** The key. */
   @EmbeddedId
   private FooKey id;
}

@Embeddable
@Data
public class FooKey implements Serializable {
    private static final long serialVersionUID = 1L;
     /** The key. */

   private String id1;
   private String id2;
}

In the specification I am trying to do

@Override
    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
 // get root type 
 root.get(property).getJavaType()

But this doesn't work for nested attributes like in this case. Is there any way I can be able to build predicates for properties in the composite key.


回答1:


Example of Equal:

     @Override
     public Predicate toPredicate(Root<Foo> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 
     builder.equal(root.get("id").get("id1"),"my val");



回答2:


You can build a function like this if you want to use multiple levels. In my experience, 2 levels are more than sufficient. But depends on you.

protected Path<Comparable> getPath(Root<EntityOrModel> root) {
    Path<Comparable> path;
    if (criteria.getKey().contains(".")) {
        String[] split = criteria.getKey().split("\\.");
        int keyPosition = 0;
        path = root.get(split[keyPosition]);
        for (String criteriaKeys : split) {
            if (keyPosition > 0) {
                path = path.get(criteriaKeys);
            }
            keyPosition++;
        }
    } else {
        path = root.get(criteria.getKey());
    }
    return path;
}

Then set

@Override
public Predicate toPredicate(Root<EntityOrModel> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
    Path<Comparable> path = getPath(root);
    // ...
    return builder.equal(path, value)
}


来源:https://stackoverflow.com/questions/36357180/can-we-build-spring-data-jpa-specification-out-of-a-composite-key-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!