title: move validation to the JPQL query level
body: <p>I am looking for a way to move the validation method from Service to Repository</p>
  <p>One Picture has one PictureData.</p>
  <p>This is the method:</p>
  <p>// TODO move validation to the JPQL query level
  .filter(pic -&gt; pic.getPictureData().getFileName() != null)</p>
  <p>This is my Service</p>
  <pre><code>@Service
  @ConditionalOnProperty(name = &quot;picture.storage.type&quot;, havingValue = &quot;file&quot;)
  public class PictureServiceFileImpl implements PictureService {
  
      private static final Logger logger = LoggerFactory.getLogger(PictureServiceFileImpl.class);
  
      @Value(&quot;${picture.storage.path}&quot;)
      private String storagePath;
  
      private final PictureRepository repository;
  
      @Autowired
      public PictureServiceFileImpl(PictureRepository repository) {
          this.repository = repository;
      }
  
      @Override
      public Optional&lt;String&gt; getPictureContentTypeById(long id) {
          return repository.findById(id)
                  // TODO move validation to the JPQL query level
                  .filter(pic -&gt; pic.getPictureData().getFileName() != null)
                  .map(Picture::getContentType);
      }
  
      @Override
      public Optional&lt;byte[]&gt; getPictureDataById(long id) {
          return repository.findById(id)
                  // TODO move validation to the JPQL query level
                  .filter(pic -&gt; pic.getPictureData().getFileName() != null)
                  .map(pic -&gt; Path.of(storagePath, pic.getPictureData().getFileName()))
                  .filter(Files::exists)
                  .map(path -&gt; {
                      try {
                          return Files.readAllBytes(path);
                      } catch (IOException ex) {
                          logger.error(&quot;Can't open picture file&quot;, ex);
                          throw new RuntimeException(ex);
                      }
                  });
      }
  
      @Override
      public PictureData createPictureData(byte[] picture) {
          String fileName = UUID.randomUUID().toString();
          try (OutputStream os = Files.newOutputStream(Path.of(storagePath, fileName))) {
              os.write(picture);
          } catch (IOException ex) {
              logger.error(&quot;Can't create picture file&quot;, ex);
              throw new RuntimeException(ex);
          }
          return new PictureData(fileName);
      }
  }
  </code></pre>
  <p>The Entities</p>
  <pre><code>@Entity
  @Table(name = &quot;pictures&quot;)
  public class Picture {
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = &quot;id&quot;)
      private Long id;
  
      @Column(name = &quot;name&quot;, nullable = false)
      private String name;
  
      @Column(name = &quot;content_type&quot;, nullable = false)
      private String contentType;
  
      @OneToOne(fetch = FetchType.LAZY, cascade= CascadeType.ALL, optional = false, orphanRemoval = true)
      @JoinColumn(name=&quot;picture_data_id&quot;)
      private PictureData pictureData;
  
      @ManyToOne
      private Product product;
  
      public Picture() {
      }
  
      public Picture(String name, String contentType, PictureData pictureData, Product product) {
          this.name = name;
          this.contentType = contentType;
          this.pictureData = pictureData;
          this.product = product;
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public String getContentType() {
          return contentType;
      }
  
      public void setContentType(String contentType) {
          this.contentType = contentType;
      }
  
      public PictureData getPictureData() {
          return pictureData;
      }
  
      public void setPictureData(PictureData pictureData) {
          this.pictureData = pictureData;
      }
  
      public Product getProduct() {
          return product;
      }
  
      public void setProduct(Product product) {
          this.product = product;
      }
  }
  
  @Entity
  @Table(name = &quot;pictures_data&quot;)
  public class PictureData {
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = &quot;id&quot;)
      private Long id;
  
      @Lob
      @Type(type=&quot;org.hibernate.type.BinaryType&quot;) // для правильной работы PostgreSQL
      @Column(name = &quot;data&quot;, length = 33554430) // для правильной hibernate-валидации в MySQL
      private byte[] data;
  
      @Column(name = &quot;file_name&quot;)
      private String fileName;
  
      public PictureData() {
      }
  
      public PictureData(byte[] data) {
          this.data = data;
      }
  
      public PictureData(String fileName) {
          this.fileName = fileName;
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public byte[] getData() {
          return data;
      }
  
      public void setData(byte[] data) {
          this.data = data;
      }
  
      public String getFileName() {
          return fileName;
      }
  
      public void setFileName(String fileName) {
          this.fileName = fileName;
      }
  }
  </code></pre>
  <p>I am struggling to get a query working in JPQL.</p>
  <pre><code>public interface PictureRepository extends JpaRepository&lt;Picture, Long&gt; {
  
      @Query (&quot;SELECT p FROM Picture p JOIN p.pictureData d WHERE d.data  IS NOT NULL &quot;)
      Picture filterPictureWherePictureDataIsNotNull ();
  }
  </code></pre>