@Spring Data MongoDB 存储库中使用 SpEL 进行聚合问题

问题描述 投票:0回答:1

我正在使用 mongodb 数据库开发 Spring Boot 应用程序,并且我有一个名为 DOCUMENT 的集合: 这是 Document.java:

@Getter
@Setter
@Document("DOCUMENT")
public class Document {

    @Id
    private String id;
    private List<String> field1;
    private String field2;
    private Date field3;
    etc...
}

我还有一个专门的存储库:

@Repository
public interface DocumentRepository extends MongoRepository<Document, String> {

    @Aggregation(
            pipeline = {
                    "{ '$match': { " +
                        "?#{ [0] == null || [0].isEmpty() ? '' : 'field1 : { $in: [0] },' }" +
                        "?#{ T(org.apache.commons.lang3.StringUtils).isBlank([1]) ? '' :             'field2 : { $regex: '.*' + [1] + '.*', $options: 'i' },' }" +
    "?#{ [2] == null ? '' : 'field3 : { $gte: [2] },' }" +
    "?#{ [2] == null ? '' : 'field3 : { $lte: [2] },' }" +
"} }"
            }
    )
    List<Document> findDocument(
            List<String> field1, String field2, Date field3LowerBound, Date Date field3UpperBound
    );

}

在我的服务层中我调用这个方法:

List<Document> documentList = documentRepository.findDocument(field1, field2, field3Lower,   field3Upper);

但我明白了:

jakarta.servlet.ServletException: Handler dispatch failed: java.lang.StackOverflowError
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1096) ~[spring-webmvc-6.0.7.jar:6.0.7]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.7.jar:6.0.7]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.7.jar:6.0.7]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.7.jar:6.0.7]
Caused by: java.lang.StackOverflowError: null
    at org.springframework.data.mongodb.util.json.JsonBuffer.read(JsonBuffer.java:50) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.JsonScanner.nextToken(JsonScanner.java:70) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingJsonReader.popToken(ParameterBindingJsonReader.java:753) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingJsonReader.readBsonType(ParameterBindingJsonReader.java:167) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:679) ~[bson-4.8.2.jar:na]
    at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:721) ~[bson-4.8.2.jar:na]
    at org.bson.AbstractBsonReader.readStartDocument(AbstractBsonReader.java:449) ~[bson-4.8.2.jar:na]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:235) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:67) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.readValue(ParameterBindingDocumentCodec.java:371) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:248) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:67) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.readValue(ParameterBindingDocumentCodec.java:371) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:248) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:67) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.readValue(ParameterBindingDocumentCodec.java:371) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:248) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:67) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.readValue(ParameterBindingDocumentCodec.java:371) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:248) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.decode(ParameterBindingDocumentCodec.java:67) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
    at org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec.readValue(ParameterBindingDocumentCodec.java:371) ~[spring-data-mongodb-4.0.4.jar:4.0.4]
etc...

我将@Date lombok注释更改为@Getter和@Setter,在debuggin时我注意到它循环遍历哈希码,但我不确定这就是问题

java spring spring-boot spring-data-mongodb spring-el
1个回答
0
投票

问题似乎是SpEL本身,我在这里复制了https://github.com/sbernardo/spring-issues-examples/tree/main/sof-questions-77705053并修改了SpEL如下:

public interface DocumentRepository extends MongoRepository<DocumentEntity, String> {

    @Aggregation(
            pipeline = {"""
                    {
                        '$match': {
                            $and: [
                                ?#{ [0] == null || [0].isEmpty() ? { _id: { $exists: true } } : { field1 : { $in: [0] } } },
                                ?#{ T(org.apache.commons.lang3.StringUtils).isBlank([1]) ? { _id: { $exists: true } } : { field2 : { $regex: '.*' + [1] + '.*', $options: 'i' } } },
                                ?#{ [2] == null ? { _id: { $exists: true } } : { field3 : { $gte: [2] } } },
                                ?#{ [3] == null ? { _id: { $exists: true } } : { field3 : { $lte: [3] } } }
                            ]
                        }
                    }
                    """
            }
    )
    List<DocumentEntity> findDocument(List<String> field1, String field2, Date field3LowerBound, Date field3UpperBound);

}

注意:我无法避免添加此处描述的参数,因此我建议使用必填字段而不是

{ _id: { $exists: true } }

我在 Spring Data Mongo 中发现这个问题来管理空值,解决方法与我的实现类似。这就是问题:https://github.com/spring-projects/spring-data-mongodb/issues/4050。请注意,问题是针对

@Query
的,但我认为是相同的。

我尝试了一些案例并且按预期工作。希望这会有所帮助。如果您找到更好的解决方案,我会想知道:D

© www.soinside.com 2019 - 2024. All rights reserved.