首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Neo4j -用于类型列表字段的自定义转换器

Neo4j -用于类型列表字段的自定义转换器
EN

Stack Overflow用户
提问于 2019-01-30 00:30:02
回答 2查看 716关注 0票数 1

我试图为嵌套对象编写自定义转换器,以便将该对象保存为Neo4j数据库中的字符串。

我在我的字段上使用@Convert注释,并传递ImageConverter.class,这是我的AttributeConverter类。

一切正常运行,我可以在Image db中保存Neo4j类的字符串表示。

但是,现在我不想使用单个映像,而是希望将List<Image>作为我的嵌套字段。在这种情况下,放置@Convert(ImageConverter.class)不起作用。

我看到有一个名为ConverterBasedCollectionConverter的类,当我有一个类型为List<LocalDateTime的字段时,这个类就会被使用。

但是,我找不到如何在自定义转换器的情况下使用这个类的例子。

请任何人帮助我在此或如果有任何其他方法使用自定义转换器在字段的类型List

在我的应用程序中,我使用的是Neo4j (3.4.1版)和Spring-data-ne4j (5.0.10.RELEASE)。我也在使用OGM。

PS:我知道,建议将嵌套对象存储为单独的节点,与父对象建立关系。但是,我的用例要求将对象存储为string属性,而不是单独的节点。

致以敬意,

V

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-30 22:19:20

这并不像我想象的那么困难。

给定一个类(片段)

代码语言:javascript
复制
@NodeEntity
public class Actor {

  @Id @GeneratedValue
  private Long id;

  @Convert(MyImageListConverter.class)
  public List<MyImage> images = new ArrayList<>();
  // ....
}

使用MyImage尽可能简单

代码语言:javascript
复制
public class MyImage {

  public String blob;

  public MyImage(String blob) {
      this.blob = blob;
  }

  public static MyImage of(String value) {
      return new MyImage(value);
  }
}

和一个转换器

代码语言:javascript
复制
public class MyImageListConverter implements AttributeConverter<List<MyImage>, String[]> {

  @Override
  public String[] toGraphProperty(List<MyImage> value) {
      if (value == null) {
          return null;
      }
      String[] values = new String[(value.size())];
      int i = 0;
      for (MyImage image : value) {
          values[i++] = image.blob;
      }
      return values;
    }

    @Override
    public List<MyImage> toEntityAttribute(String[] values) {
      List<MyImage> images = new ArrayList<>(values.length);
      for (String value : values) {
          images.add(MyImage.of(value));
      }
      return images;
    }
}

将在“保存”上打印以下调试输出,我认为这是您想要的:

UNWIND {rows} as row CREATE (n:Actor) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, {type} as type with params {type=node, rows=[{nodeRef=-1, props={images=[blobb], name=Jeff}}]}

尤其是图像部分。

测试方法如下所示

代码语言:javascript
复制
@Test
public void test() {
    Actor jeff = new Actor("Jeff");
    String blobValue = "blobb";
    jeff.images.add(new MyImage(blobValue));
    session.save(jeff);
    session.clear();
    Actor loadedActor = session.load(Actor.class, jeff.getId());
    assertThat(loadedActor.images.get(0).blob).isEqualTo(blobValue);

}
票数 2
EN

Stack Overflow用户

发布于 2019-01-30 23:32:29

我想出了解决问题的办法。因此,如果您想要另一个解决方案以及@meistermeier提供的解决方案,您可以使用以下代码。

代码语言:javascript
复制
public class ListImageConverter extends ConverterBasedCollectionConverter<Image, String>{

public ListImageConverter() {
    super(List.class, new ImageConverter());
}

@Override
public String[] toGraphProperty(Collection<Image> values) {
    Object[] graphProperties = super.toGraphProperty(values);
    String[] stringArray = Arrays.stream(graphProperties).toArray(String[]::new);
    return stringArray;
}

@Override
public Collection<Image> toEntityAttribute(String[] values) {
    return super.toEntityAttribute(values);
}

}

ImageConverter类只是实现了AttributeConverter<Image, String>,其中我将图像对象序列化和反序列化到json。

我选择采用这种方法,因为我在一个对象中有Image字段,在另一个对象中有List<Image>字段。因此,只要将@Convert(ListImageConverter.class)更改为@Convert(ImageConverter.class),我就可以在Neo4j数据库中保存列表和单个对象。

注意:如果需要,可以跳过重写toEntityAttribute方法。它并没有增加多少价值。但是,您必须覆盖toGraphProperty,就像在Neo4j代码中一样,它检查是否存在名称为toGraphProperty的声明方法。

希望这能帮到别人!

致以敬意,

V

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54431684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档