使用模拟更新List时发生StackOverflowError

时间:2018-01-12 15:13:56

标签: java mongodb spring-data stack-overflow

当尝试在下面测试我的updateFoos方法时,使用mongo上的spring-data更新字段List<Foo> foos,它失败了,StackOverflowError的模拟Foo列表。它适用于Foo的真实实例。

春天的东西&#39;版本:

  • spring-data-mongodb:1.9.1
  • spring-data-commons:1.12.1
  • spring-aop / beans / context / core / expression / tx:4.5.2

以下是更新方法:

public void updateFoos(String id, List<Foo> foos) {
  mongoOps.updateFirst(query(where(FIELD_ID).is(id)),
                       new Update().set(FIELD_FOOS, foos),
                       clazz);
}

以下是测试:

@Test
public void givenPersistedBar_whenUpdateFoos_thenUpdatesThem() {
  List<Foos> foos = Collections.nCopies(10, mock(Foo.class));

  barDao.updateFoos(ID, foos);
}

这是堆栈跟踪

java.lang.StackOverflowError
    at java.security.AccessController.doPrivileged(Native Method)
    at java.io.FilePermission.init(FilePermission.java:203)
    at java.io.FilePermission.<init>(FilePermission.java:277)
    at sun.net.www.protocol.file.FileURLConnection.getPermission(FileURLConnection.java:225)
    at sun.net.www.protocol.jar.JarFileFactory.getPermission(JarFileFactory.java:156)
    at sun.net.www.protocol.jar.JarFileFactory.getCachedJarFile(JarFileFactory.java:126)
    at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:81)
    at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122)
    at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:152)
    at java.net.URL.openStream(URL.java:1045)
    at java.lang.ClassLoader.getSystemResourceAsStream(ClassLoader.java:1331)
    at java.lang.Class.getResourceAsStream(Class.java:2221)
    at org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass(LocalVariableTableParameterNameDiscoverer.java:101)
    at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:87)
    at org.springframework.core.PrioritizedParameterNameDiscoverer.getParameterNames(PrioritizedParameterNameDiscoverer.java:65)
    at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.buildPreferredConstructor(PreferredConstructorDiscoverer.java:109)
    at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.<init>(PreferredConstructorDiscoverer.java:74)
    at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:93)
    at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.<init>(BasicMongoPersistentEntity.java:75)
    at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:91)
    at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:39)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:299)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:489)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:446)
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:689)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:314)
...

1 个答案:

答案 0 :(得分:2)

Spring Data MongoDB分析您要存储在数据库中的实体。 为此,它查看要使用反射存储的类的属性。

模拟很可能具有形成循环的属性。 很可能类似于对信息的引用,如何模仿应该表现出来,也提到了模拟。 因此,你得到一个无限循环。

如果您想知道所涉及的确切属性是什么,只需在堆栈跟踪中提到的行处放置一个断点并进行调试。

修复它只是不要使用模拟。 我不确定为什么会使用模拟来测试存储库。 如果您不想测试存储库,但使用存储库的某些代码会模拟存储库。