Мы рады сообщить, что наше сообщество начинает обрастать экспертами, и мы будем знакомить вас с их мнением. Встречайте, Михаил Поливаха, коммитер Spring Data JDBC (Relational), не удержался от комментария по вопросу поддержки проекций в разных модулях Spring Data. Ниже прямая речь Михаила.



Надо сказать, что projection-ы, как функциональность, должна быть доступна во всех модулях spring-data. Вопрос в том, что еще не все модули ее поддержку реализовали до конца.

Наивный читатель мог бы предположить, что поскольку в spring-data-jdbc есть поддержка как interface based projection-ов, так и dynamic projection-ов, то вот это заработает:





public interface MyEntityRepository extends CrudRepository<MyEntity, Long> {



<T> Optional<T> findProjectionByStatus(String status, Class<T> clazz);

}



@Data

@EqualsAndHashCode(onlyExplicitlyIncluded = true)

@Accessors(chain = true)

@Table

public class MyEntity {



@Id

@EqualsAndHashCode.Include

private Long id;



private String status;



@CreatedDate

private Instant createdAt;

}



interface MyEntityInterfaceProjection {

String status();



Long id();

}



@Test

void whenDynamicProjectsAreInUseViaInterfaces_thenBlast() {

saveInitialEntity();

Optional<MyEntityInterfaceProjection> active = myEntityRepository.findProjectionByStatus("active", MyEntityInterfaceProjection.class);



Assertions.assertThat(active)

.isPresent()

.hasValueSatisfying(myEntityProjection -> {

Assertions.assertThat(myEntityProjection.id() != null && myEntityProjection.status().equalsIgnoreCase("active")).isTrue();

});

}



@NotNull

private MyEntity saveInitialEntity() {

MyEntity myEntity = new MyEntity();

myEntity.setStatus("active");

return myEntityRepository.save(myEntity);

}





Но данный код сгенерит ошибку глубоко в недрах JdbcQueryCreator-a:





java.lang.IllegalStateException: SELECT does not declare a select list

at org.springframework.data.relational.core.sql.SelectValidator.doValidate(SelectValidator.java:57)

at org.springframework.data.relational.core.sql.SelectValidator.validate(SelectValidator.java:49)

at org.springframework.data.relational.core.sql.DefaultSelectBuilder.build(DefaultSelectBuilder.java:207)

at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.complete(JdbcQueryCreator.java:173)

at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.complete(JdbcQueryCreator.java:66)





Связано это с тем, что на данный момент spring-data-jdbc просто не умеет переваривать динамические проджекшены для инфтерфейсов 🙂

Про это мы знаем, бага на это дело пока нет, если он кому-либо важен - можем завести. Хочу также напомнить, что если есть какие-либо инициативы для нововведений в spring-data-jdbc - можно оставлять в комментариях или писать мне в ЛС.