Search code examples
javahibernatejpaormcriteria

How to create Specification with filtering expression when working with field represents collection of objects?


I have next entities:

Attachment:

@Data
@ToString
@Entity
@EqualsAndHashCode
@Accessors(chain = true)
public class Attachment {
   private Long id;
   private String attachmentName;
   private String code;
}

Document:

@Data
@ToString
@Entity
@EqualsAndHashCode
@Accessors(chain = true)
public class Document{
   private Long id;
   private String documentName;

   @LazyCollection(LazyCollectionOption.FALSE)
   @OrderBy
   @OneToMany(mappedBy = "...", orphanRemoval = true, cascade = CascadeType.ALL)
   private List<Attachment> attachments = new ArrayList<>();
}

I need to build Specification (I should use only Specification because document service was written by 3rd party and requires Specification as Param) which must contain filtering by attachmentName. It should looks something like this:

public class DocumentPredicate {
   public Specification<Document> getPredicate(String attachmentFilteringName) {
      Specifications<T> result = Specifications.where(AnotherSpecification);

      if (attachmentFilteringName != null) {
            result = result.and((root, query, cb) ->
                    cb.equal(root.get("attachments"), attachmentFilteringName));
      }
   }

}

I have tried a lot of solutions but all of them doesn't resolve this task. The main problems is:

  1. I can't do smth like: root.get("attachments").get("0"), i.e. I can't use list elements in predicate. Because I get exception, of course.
  2. I cant use cb.in() because I have only attachmentFileName and doesnt have other fields for Attachment equals method proper work.

Solution

  • if (attachmentFilteringName != null) { result = result.and((root, query, cb) -> cb.equal(root.join("attachments").get("attachmentName"), attachmentFilteringName)); }