【问题标题】:Spring Data Elastic and recursive document mappingSpring Data 弹性和递归文档映射
【发布时间】:2018-04-18 22:59:32
【问题描述】:

我有一个 Spring 应用程序,我在其中使用 Spring Data Elastic 访问 Elasticsearch 数据。

数据模型需要递归,这让 Spring Data Elastic 很头疼,因为我在尝试运行我的应用程序时遇到了 java.lang.StackOverflowError: null

这就是我的班级的样子:

@Document(indexName = "conversation", type = "folder-tree")
public class MailFolderTreeSearchEntity extends DeletableEntity {

  @Id
  @Field(index = not_analyzed)
  private String id;

  @Field(type = FieldType.String, index = not_analyzed)
  private String owner;

  @Field(type = FieldType.Nested)
  private List<MailFolder> folderList;

  ...

嵌套类:

public class MailFolder {

  @Field(type = FieldType.String, index = not_analyzed)
  private String id;

  @Field(type = FieldType.String, index = not_analyzed)
  private String name;

  @Field(type = FieldType.String, index = not_analyzed)
  private String icon;

  @Field(type = FieldType.Nested)
  private List<MailFolder> children;

  ...

这是我在尝试运行代码时遇到的异常:

Caused by: java.lang.StackOverflowError: null
at sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature(SignatureParser.java:310) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:289) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:283) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseTypeArgument(SignatureParser.java:436) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseTypeArguments(SignatureParser.java:396) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parsePackageNameAndSimpleClassTypeSignature(SignatureParser.java:346) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature(SignatureParser.java:310) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:289) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:283) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseTypeSignature(SignatureParser.java:485) ~[na:1.8.0_91]
at sun.reflect.generics.parser.SignatureParser.parseTypeSig(SignatureParser.java:188) ~[na:1.8.0_91]
at sun.reflect.generics.repository.FieldRepository.parse(FieldRepository.java:52) ~[na:1.8.0_91]
at sun.reflect.generics.repository.FieldRepository.parse(FieldRepository.java:42) ~[na:1.8.0_91]
at sun.reflect.generics.repository.AbstractRepository.<init>(AbstractRepository.java:74) ~[na:1.8.0_91]
at sun.reflect.generics.repository.FieldRepository.<init>(FieldRepository.java:48) ~[na:1.8.0_91]
at sun.reflect.generics.repository.FieldRepository.make(FieldRepository.java:66) ~[na:1.8.0_91]
at java.lang.reflect.Field.getGenericInfo(Field.java:105) ~[na:1.8.0_91]
at java.lang.reflect.Field.getGenericType(Field.java:247) ~[na:1.8.0_91]
at org.springframework.core.SerializableTypeWrapper$FieldTypeProvider.getType(SerializableTypeWrapper.java:285) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.core.SerializableTypeWrapper.forTypeProvider(SerializableTypeWrapper.java:150) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.core.ResolvableType.forType(ResolvableType.java:1333) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.core.ResolvableType.forField(ResolvableType.java:1053) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.core.GenericCollectionTypeResolver.getCollectionFieldType(GenericCollectionTypeResolver.java:79) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.data.elasticsearch.core.MappingBuilder.getFieldType(MappingBuilder.java:321) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.isEntity(MappingBuilder.java:312) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.mapEntity(MappingBuilder.java:132) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.mapEntity(MappingBuilder.java:137) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.mapEntity(MappingBuilder.java:137) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.mapEntity(MappingBuilder.java:137) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]
at org.springframework.data.elasticsearch.core.MappingBuilder.mapEntity(MappingBuilder.java:137) ~[spring-data-elasticsearch-2.1.3.RELEASE.jar:na]

有什么想法吗?

【问题讨论】:

  • “数据模型需要递归” - ES 中没有递归映射的概念,所以不要指望库支持它。
  • 也许我使用了错误的术语,但我希望任务很明确:我想存储可以在其内部存储相同类型文档的文档。这有可能吗?
  • 这是可能的,除非您不能使用任何 Java 级递归来定义该映射。您需要通过复制粘贴定义来进行有限映射。或者切换到动态映射,不知道Spring数据是否支持。

标签: java recursion spring-data stack-overflow spring-data-elasticsearch


【解决方案1】:

经过多天的研究,我找到了解决方案,所以我想与社区分享它,也许它对其他人也有用。

为避免 StackOverflowExpcetion,当 Spring Data Elasticsearch 尝试映射您的递归模式时,您必须在 @Field 注释中使用 ignoreFields 属性,因此映射器不会进入无限循环。

这就是我的 MailFolder 类目前的样子:

...
public class MailFolder {

@Field(type = FieldType.String, index = not_analyzed)
private String id;

@Field(type = FieldType.String, index = not_analyzed)
private String name;

@Field(type = FieldType.String, index = not_analyzed)
private String icon;

@Field(type = FieldType.Boolean, index = not_analyzed)
private boolean system;

@Field(type = FieldType.Nested, ignoreFields = {"children"})
private List<MailFolder> children;
...

【讨论】:

  • 我使用的是 ES 7.6.2。当我尝试使用递归嵌套时,会创建索引但映射为空。也尝试使用您的解决方案,但我仍然无法生成映射
猜你喜欢
  • 2023-03-02
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多