【问题标题】:Spring data mongo with more than 10 parameters10多个参数的spring data mongo
【发布时间】:2017-04-27 06:46:05
【问题描述】:

我想检查集合中是否已经存在具有 15 个相等字段的文档。而且@Query注解似乎不能处理超过10个参数。以下类在调用重复时抛出异常。

public interface ReportingentriesRepository extends MongoRepository<Reportingentries, String> {

    @Query(exists = true,value = "{ 'foo': ?0,'foo1': ?1,'foo2': ?2,'foo3': ?3,'foo4': ?4,'foo5': ?5,'foo6': ?6,'foo7': ?7,'foo8': ?8,'foo9': ?9, 'foo10': ?10}")
    boolean isDuplicated(String value0, String value1, String value2, String value3, String value4, String value5, String value6, String value7, String value8, String value9, String value10);
}

例外是:

java.util.NoSuchElementException: Could not to find binding for placeholder '?11'.
    at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder$BindingContext.getBindingFor(ExpressionEvaluatingParameterBinder.java:341) ~[spring-data-mongodb-1.10.0.RELEASE.jar:?]
    at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.replacePlaceholders(ExpressionEvaluatingParameterBinder.java:120) ~[spring-data-mongodb-1.10.0.RELEASE.jar:?]
    at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.bind(ExpressionEvaluatingParameterBinder.java:91) ~[spring-data-mongodb-1.10.0.RELEASE.jar:?]
    at org.springframework.data.mongodb.repository.query.StringBasedMongoQuery.createQuery(StringBasedMongoQuery.java:130) ~[spring-data-mongodb-1.10.0.RELEASE.jar:?]
    at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(AbstractMongoQuery.java:84) ~[spring-data-mongodb-1.10.0.RELEASE.jar:?]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483) ~[spring-data-commons-1.13.0.RELEASE.jar:?]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.0.RELEASE.jar:?]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.13.0.RELEASE.jar:?]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.0.RELEASE.jar:?]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at com.sun.proxy.$Proxy94.isDuplicated(Unknown Source) ~[?:?]
    at com.company.importer.Application.run(Application.java:29) [classes/:?]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at com.company.importer.Application.main(Application.java:22) [classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_92]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_92]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_92]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_92]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.1.RELEASE.jar:1.5.1.RELEASE]

是我遗漏了什么还是 spring 根本不支持这个?

我正在使用 spring-boot-starter-data-mongodb:1.5.1.RELEASE

【问题讨论】:

  • 我不认为这是因为查询参数的数量。查询语法应该有问题。 @Query 可以处理超过 10 个参数
  • 做我的客人,告诉我在哪里...我没有胶水。这是我可以用 11 个参数成像的最简单的查询,但它失败了。
  • 从错误消息看来您正在使用占位符 '?11' 。在 ExpressionEvaluatingParameterBinder::getBindingFor 方法中放置一个断点并查看传递了哪些值。我无法重现这一点。对我来说,即使有 15 个参数,它也能正常工作
  • 看起来像一个错误。想在jira.spring.io/browse/DATAMONGO 提交票证吗?

标签: java spring mongodb spring-data


【解决方案1】:

Spring 数据还有一个注释,有助于将方法参数视为查询参数。

注解:@Param

这个注解可以和方法参数本身一起使用。请找到以下格式,它可以帮助扩展方法参数计数以与 spring 数据一起使用。

说明:可以包含N号。带有 @Param 注释的方法参数。请在下面找到有效的表达式来编写注释。

@Param("param0")

现在,当你添加这个带有方法参数的@Param注解时,你必须在@Query中指定参数,前缀为colon (:)。在下面的查询中类似于 param0

@Query("{"query": {"bool": {"must": [{ "match": {"userId": ":param0" }}]}}}")

完整示例:可以看到org_id是查询参数。

@Query("{"query": {"bool": {"must": [{ "match": {"userId": ":org_Id"}}]}}}")
List<User> getByOrgId(@Param("org_Id") String orgId)

【讨论】:

    【解决方案2】:

    我不知道你是否已经解决了这个问题,但我遇到了两个不同的问题,你可以在这里查看:how-to-use-the-same-parameter-for-multiple-conditions

    第一个问题是我想重复一个参数,所以我尝试了@Param,然后我开始遇到和你一样的错误,我不能使用超过 10 个参数。

    所以我决定调试绑定过程并解决这两个问题,在参数中添加一个简单的单引号,如下所示(检查参数编号 6):

    @Query(value = "{ companyType: ?0, companyId: ?1, eventType: ?2, " +
                "delivered: ?3, createdAt: { $gt: ?4, $lt: ?5 }, " +
                "$or: [{ $or: [{ $or: [{ $or: [{ requestPayload.sponsorGovernmentId: ?6 }, " +
                "{requestPayload.buyerGovernmentId: '?6'}] }, {requestPayload.supplierGovernmentId: '?6'}] }, " +
                "{requestPayload.invoiceNumber: ?7}]}, {requestPayload.externalId: ?8}] }")
    

    之后我可以使用超过 10 个参数并重复它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-21
      • 2013-05-20
      • 2020-08-11
      • 2019-04-01
      • 2015-07-06
      • 2016-10-01
      • 2021-03-16
      • 1970-01-01
      相关资源
      最近更新 更多