spring-data-r2dbc icon indicating copy to clipboard operation
spring-data-r2dbc copied to clipboard

Exists method throws "SELECT does not declare a select list"

Open bskorka opened this issue 2 years ago • 3 comments

In my app I have two R2dbcRepository - one for object with Long ID, second with String ID.

@Repository
public interface ObjectARepository extends R2dbcRepository<ObjectA, Long> {

    Mono<Boolean> existsObjectAByFieldAAndFieldB(Integer fieldA, EnumName fieldB);

}
@Repository
public interface ObjectBRepository extends R2dbcRepository<ObjectB, String> {

    Mono<Boolean> existsObjectBByFieldAAndFieldB(String fieldA, Integer fieldB);

}

When I try to test it I'm getting - java.lang.IllegalStateException: SELECT does not declare a select list for ObjectBRepository while everything works fine for ObjectARepository.

If I write query for second repository like that:

@Query("SELECT EXISTS(SELECT * FROM objectBTable WHERE fieldA = :fieldA AND fieldB = :fieldB);")
    Mono<Boolean> existsObjectBByFieldAAndFieldB(String fieldA, Integer fieldB);

It works.

Are there any differences for a repositories where ID is Long and String? Or it may be related to something else?

Spring Boot version - 2.7.1 io.spring.dependency-management version - 1.0.11.RELEASE MariaDB version - 10.5.12

bskorka avatar Aug 03 '22 09:08 bskorka

Can you provide a bit of code how ObjectA and ObjectB look like?

mp911de avatar Aug 05 '22 07:08 mp911de

Sure, I will try to also provide some example repo, but didn't have time for it in last week. ObjectA:

@Builder(toBuilder = true)
@AllArgsConstructor
@Data
@Table("objectATable")
public class ObjectA {

    @Id
    private Long id;

    @Column("fieldA")
    private Integer fieldA;

    @Column("fieldB")
    private EnumName fieldB;

    @Column("fieldC")
    private String fieldC;

    @Column("created")
    @CreatedDate
    private LocalDateTime created;

    @Column("updated")
    @LastModifiedDate
    private LocalDateTime updated;

    public enum EnumName {
        STH_1,
        STH_2
    }

}

ObjectB:

@Builder(toBuilder = true)
@AllArgsConstructor
@Data
@Table("objectBTable")
public class ObjectB {

    @Column("fieldA")
    private String fieldA;

    @Column("fieldB")
    private Integer fieldB;

    @Column("innerCollection")
    private List<InnerCollection> innerCollection; // that field is mapped to JSON using Converter class

    @Column("created")
    @CreatedDate
    private LocalDateTime created;

}

bskorka avatar Aug 08 '22 09:08 bskorka

Okay, the difference is that ObjectB does not declare an identifier. We should reconsider our approach for the exists query to select a placeholder (something like SELECT 1 FROM objectBTable) to avoid the problem.

mp911de avatar Aug 08 '22 10:08 mp911de