Spring Data Couchbase:具有反应性存储库的投影

时间:2019-08-28 18:50:00

标签: spring-data spring-data-couchbase

使用DTO投影方法的反应式Couchbase存储库失败

CouchbaseQueryExecutionException: Query returning primitive got more values than expected: 5

反应式存储库是否支持DTO投影?

我正在尝试使用反应性存储库实现一个非常基本的DTO投影存储库方法:我有两个Couchbase @Documents和一个表示投影的接口。查询存储库方法使用接口投影从两个文档中投影一些属性。 经过一些调试后,我发现由于org.springframework.data.repository.query.QueryMethod中的此检查而导致失败:

public boolean isQueryForEntity() {
    return getDomainClass().isAssignableFrom(getReturnedObjectType());
}

org.springframework.data.couchbase.repository.query.ReactiveAbstractN1qlBasedQueryexecuteDependingOnType()呼叫。

显然,无法从投影接口分配文档实体。

这里是有问题的原型类: 第一份文件:

@Document
@Data
public class DocMetadata {
    @Field
    private String type;

    @Id
    @Field
    private String id;

    @Field
    private String title;
}

第二个文档:

@Document
@Data
public class Doc {

    @Field
    private String type;

    @Id
    @Field
    private String id;

    @Field
    private String metadataId;

    @Field
    private Status status;

    @Field
    private String releaseDate;
}

投影界面:

public interface DashboardDocProjection {

    String getId();          // from Doc.id
    String getReleaseDate(); // from Doc.releaseDate
    String getStatus();      // from Doc.status

    String getTitle();       // from DocMetadata.title

}

还有存储库:

@Repository
public interface CouchbaseDocRepository extends
        ReactiveCouchbaseSortingRepository<Doc, String> {

    @Query("<query to select Doc join DocMetadata projecting some attributes from both>")
    Flux<DashboardDocProjection> getProjection();

}

作为一种解决方法,我可以使用代表表示投影属性的单独@Document和该文档类型的单独存储库来进行投影,但是它需要更多样板代码,并且通常不太好。映射示例如下:

@Query("SELECT META(`doc1`).id AS _ID, META(`doc1`).cas AS _CAS, "
    + “doc2.title as title, "
    + "`doc1`.id as versionId, "
    + "`doc1`.attribute2 as attribute2 "
    + "FROM #{#n1ql.bucket} `doc1` "
    + "JOIN #{#n1ql.bucket} doc2 ON KEYS […] "
    + "WHERE `doc1`._class = "\"<doc1.class>\" "
    + "AND `doc1`.attribute1 = $1 "
    + "AND `doc1`.attribute2 = $2 "
    + "ORDER BY `doc1`.id ASC "
    + "LIMIT $3 OFFSET $4;")
Flux<DashboardEntry> findAll(
    String attribute1Value, String attribute2Value, Integer limit, Integer offset);

0 个答案:

没有答案