Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverflowError when calling repository method [DATAMONGO-2465] #3320

Closed
spring-projects-issues opened this issue Feb 6, 2020 · 3 comments
Closed
Assignees
Labels
in: mapping in: repository status: declined type: bug

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Feb 6, 2020

Eduard Onofrei opened DATAMONGO-2465 and commented

I am getting a StackOverflowError when calling a method of my MongoDB repository interface:

public interface TermRepository extends MongoRepository<Term, String>, QuerydslPredicateExecutor<Term> {
    // [...]
    @Query("{$or:[{'apis' : {$in : ?0 } }, {$text:{$search:?1}}]}")
    Page<Term> globalSearch(List<DBRef> apis, String searchKeyword, Pageable pageable);
}
  • apis is a list with just one DBRef: new DBRef("api", new ObjectId("5e3ad9faaafa595898b6a682"))

  • searchKeyword equals "accounts"

  • pageable is {{Page request [number: 0, size 37, sort: UNSORTED]}}. If size is 36, it doesn't throw the StackOverflowError!

  • The query gets translated into

{
    $or: [{
        'apis': {
            $in: [{
                '$ref': 'api',
                '$id': ObjectId('5e3ad9faaafa595898b6a682')
            }]
        }
    }, {
        $text: {
            $search: 'account'
        }
    }]
}
  • If I execute the query directly in mongo, it returns 55 elements.
  • I've tried to increase thread stack to -Xss1G (it's a lot, I know), and it just keeps filling the stack slowly and won't return. If I rerun the test with a page size of 36, it returns immediately.

Does anyone have a clue what's happening?

The Term:

public class Term {

    @Id
    private String id;

    @NotBlank
    @TextIndexed
    @JsonProperty
    private String name;

    @NotBlank
    @TextIndexed
    @JsonProperty
    private String objectType;

    @Transient
    @JsonProperty
    private String snakeCase;

    @NotEmpty
    @JsonProperty
    private List<String> functionalCategories;

    @NotNull
    @JsonProperty
    private TermTypeEnum termType;

    @NotEmpty
    @JsonProperty
    private Map<String, String> description;

    @Setter
    @NotNull
    @JsonProperty
    private TermStateEnum state;

    @NotBlank
    @TextIndexed
    @JsonProperty
    private String example;

    @DBRef
    @NotNull
    @Indexed
    @JsonProperty
    private List<Api> apis;

    @DBRef
    @NotNull
    @JsonProperty
    private User contributor;

    @NotBlank
    @TextIndexed
    @JsonProperty
    private String version;

    @DBRef
    @JsonProperty
    private Map<String, Term> attributes;
}

The stacktrace: https://pastebin.com/y0XYt7p6

Although there might be a circular reference because Term has an attribute Map<String, Term>, I think it's not a circular reference what is producing the stack overflow.

Doing some debug, I saw that the stack overflow occurs because in the end, spring-data keeps instantiating this Term only (not others, so I don't see the circular reference):

Term(id=5e3ad9faaafa595898b6a7ea, name=debitCurrency, objectType=string, snakeCase=debit_currency, functionalCategories=null, termType=BODY, description={"english"=Debit Currency.}, state=PROPOSED, example=null, apis=[Api(id=5e3ad9faaafa595898b6a67f, name=Payments-1.0.1, description=null, responsible=null)], contributor=null, version=null, attributes=null)

Which in turn does not reference other terms.

Here is another Term, just for comparison:

Term(id=5e3ad9faaafa595898b6a6c8, name=displayCardNumber, objectType=string, snakeCase=display_card_number, functionalCategories=null, termType=BODY, description={"english"=Related card number to the account.}, state=PROPOSED, example=null, apis=[Api(id=5e3ad9faaafa595898b6a682, name=Accounts-1.0.2, description=null, responsible=null)], contributor=null, version=null, attributes=null)

I see no difference, but debitCurrency produces the stack overflow and displayCardNumber doesn't


Affects: 2.2.4 (Moore SR4)

Reference URL: https://stackoverflow.com/questions/60082035/stackoverflowerror-when-calling-spring-data-mongodb-repository-method-with-a-pag

Attachments:

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2020

Christoph Strobl commented

Can you please provide a sample/gist that reproduces the error?

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2020

Eduard Onofrei commented

Attached a sample project. Just run my.project.controller.TermControllerTest.

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 14.526 s <<< FAILURE! - in my.project.controller.TermControllerTest[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 14.526 s <<< FAILURE! - in my.project.controller.TermControllerTestorg.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError at my.project.controller.TermControllerTest.findAll(TermControllerTest.java:73)

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Feb 10, 2020

Eduard Onofrei commented

I've come up with a workaround that consists of making the @DBRef of attributes, lazy=true, and implementing a custom serializer of the class "Term", wich has the self-reference (or circular reference). The reason of implementing the custom serializer, is that I can save a set of the objects that have already been serialized, and if I have to seralize an object again, I just don't

@spring-projects-issues spring-projects-issues added type: bug status: declined in: repository in: mapping labels Dec 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: mapping in: repository status: declined type: bug
Projects
None yet
Development

No branches or pull requests

2 participants