使用DTO查询Couchbase文档片段触发InvalidDataAccessApiUsageException错误
问题:Spring Data Couchbase自定义查询返回DTO时出现属性查找错误
错误信息:
org.springframework.dao.InvalidDataAccessApiUsageException: Required property docTypeVersion not found for class java.util.Optional; nested exception is java.lang.IllegalStateException: Required property docTypeVersion not found for class java.util.Optional
相关代码与文档信息
Repository类
@Repository @Scope("efatura_islem") @Collection("gib_thread_process_non_verified") public interface ThreadProcessCouchbaseRepository extends CouchbaseRepository<ThreadProcessCouchbaseEntity, String> { @Query("SELECT meta(gtp).id AS __id , gtp.doc_type_version FROM gib_thread_process_non_verified AS gtp WHERE gtp.zip_path=$documentInstanceIdentifier") ResponseDto selectApplicationResponseInfo(String documentInstanceIdentifier); }
DTO类
@Data @Document public class ResponseDto implements Serializable { @Field("doc_type_version") private String docTypeVersion; }
Couchbase文档内容
{ "_class": "tr.gov.gib.efatura.core.entity.couchbase.ThreadProcessCouchbaseEntity", "calc_hash": "6DB58D42B042F975A7E68464C8E18FE5", "client": "10.233.92.0", "doc_date_time": "2023-08-09T19:24:53", "doc_type": "SYSTEMENVELOPE", "doc_type_version": "1.2", "error": "ZARF_BASARIYLA_ISLENDI", "issue_date": "2023-08-09", "gib_elements": [ { "element_type": "APPLICATIONRESPONSE", "fKey": "20548227-BDB9-4A7E-B873-FB7B8E3E2BCB", "item_count": 1, "oid": "31ll52grm01001" } ], "header_version": "1.0", "state_code": "1200", "zip_path": "20548227-BDB9-4A7E-B873-FB7B8E3E2BCB.zip" }
文档元数据
{ "meta": { "id": "20548227-BDB9-4A7E-B873-FB7B8E3E2BCB", "rev": "1178-177a01ea20e300000000000002000000", "expiration": 0, "flags": 33554432, "type": "json" }, "xattrs": {} }
问题原因
- DTO误用
@Document注解:@Document是标记Couchbase实体类的注解,DTO仅作为查询结果的传输对象,不需要该注解。Spring Data Couchbase会将带@Document的类视为实体处理,尝试映射元数据与实体属性,导致逻辑混淆。 - 查询返回多余字段且无对应映射:查询语句返回了
meta(gtp).id AS __id,但DTO中没有对应字段,Spring Data在处理结果时触发异常映射逻辑,错误地在Optional类中查找目标属性。
解决方案
1. 移除DTO上的@Document注解
将ResponseDto改为普通传输对象,仅保留必要的注解:
@Data public class ResponseDto implements Serializable { @Field("doc_type_version") private String docTypeVersion; }
2. 调整查询语句,移除不必要的__id返回
如果不需要文档ID,直接查询所需字段即可:
@Query("SELECT gtp.doc_type_version FROM gib_thread_process_non_verified AS gtp WHERE gtp.zip_path=$documentInstanceIdentifier") ResponseDto selectApplicationResponseInfo(String documentInstanceIdentifier);
3. 若需返回ID,为DTO添加对应字段
如果确实需要文档ID,在DTO中添加映射字段:
@Data public class ResponseDto implements Serializable { @Field("__id") private String id; @Field("doc_type_version") private String docTypeVersion; }
4. 正确使用Optional<ResponseDto>作为返回类型
确保前几步配置正确后,若查询可能返回空结果,可将返回类型改为Optional<ResponseDto>:
Optional<ResponseDto> selectApplicationResponseInfo(String documentInstanceIdentifier);
内容的提问来源于stack exchange,提问作者Anıl Emre Özçelik
相关产品推荐
相关产品推荐

