Я получаю StackOverflowError при вызове метода моего интерфейса хранилища MongoDB:
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
- это список только с одним DBRef: new DBRef ("api" , новый ObjectId ("5e3ad9faaafa595898b6a682"))
searchKeyword
равен "account"
pageable
равен Page request [number: 0, size 37, sort: UNSORTED]
. Если size
равно 36, он не выдает ошибку StackOverflowError! - Запрос переводится в
{
$or: [{
'apis': {
$in: [{
'$ref': 'api',
'$id': ObjectId('5e3ad9faaafa595898b6a682')
}]
}
}, {
$text: {
$search: 'account'
}
}]
}
- Если я выполняю запрос непосредственно в mon go, он возвращает 55 элементов.
- Я пытался увеличить стек потоков до -Xss1G (это много, я знаю), и он просто медленно заполняет стек и не возвращается. Если я перезапущу тест с размером страницы 36, он сразу же вернется.
Кто-нибудь знает, что происходит?
Термин:
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;
}
Stacktrace: https://pastebin.com/y0XYt7p6
Хотя может существовать циклическая ссылка, поскольку Term имеет атрибут Map Я думаю, что это не круговая ссылка, которая вызывает переполнение стека.
Выполняя некоторую отладку, я увидел, что переполнение стека происходит, потому что в конце spring-data продолжает создавать только этот термин (не другие, поэтому я не вижу круговой ссылки):
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)
Что, в свою очередь, не ссылается на другие термины.
Вот еще один термин, просто для сравнения:
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)
Я не вижу разницы, но debitCurrency
вызывает переполнение стека, а displayCardNumber
- нет.