Neo4j - 列表类型字段的自定义转换器 [英] Neo4j - Custom converter for field of type List
问题描述
我正在尝试为嵌套对象编写自定义转换器,以便该对象在 Neo4j 数据库中保存为字符串.
I am trying to write a custom converter for a nested object so that this object gets saved as string in Neo4j database.
我在我的字段上使用 @Convert
注释并传递 ImageConverter.class
这是我的 AttributeConverter
类.
I am using @Convert
annotation on my field and passing ImageConverter.class
which is my AttributeConverter
class.
一切正常,我可以在 Neo4j db 中保存 Image
类的字符串表示.
Everything works fine as expected and I am able to save string representation of Image
class in Neo4j db.
但是,现在我想要将 List
作为我的嵌套字段而不是单个图像.在这种情况下,放置 @Convert(ImageConverter.class)
不起作用.
However, now instead of single image I want to have List<Image>
as my nested field. In this case, putting @Convert(ImageConverter.class)
doesn't work.
我看到有一个名为 ConverterBasedCollectionConverter
的类,当我有一个 List
I see that there is a class called ConverterBasedCollectionConverter
which gets used when I have a field of type List<LocalDateTime
.
但是,我找不到关于如何在自定义转换器的情况下使用此类的任何示例.
However, I couldn't find any exammples on how to use this class in case of custom converters.
请任何人帮我解决这个问题,或者如果有任何其他方法可以在 List
类型的字段上使用自定义转换器.
Please can anyone help me with this or if there is any other approach to use custom converter on field of type List
.
我在我的应用程序中使用 Neo4j(版本 3.4.1)和 Spring-data-neo4j(5.0.10.RELEASE).我也在用 OGM.
I am using Neo4j (version 3.4.1) and Spring-data-neo4j (5.0.10.RELEASE) in my application. I am also using OGM.
PS:我知道建议将嵌套对象存储为与父对象建立关系的单独节点.但是,我的用例要求将对象存储为字符串属性而不是单独的节点.
PS: I am aware that it is advised to store nested objects as separate node establishing a relationship with parent object. However, my use case demands that the object be stored as string property and not as separate node.
问候,
V
推荐答案
这并不像我想象的那么难.
It is not so difficult as I assumed it would be.
给定一个类(片段)
@NodeEntity
public class Actor {
@Id @GeneratedValue
private Long id;
@Convert(MyImageListConverter.class)
public List<MyImage> images = new ArrayList<>();
// ....
}
使用 MyImage
尽可能简单
public class MyImage {
public String blob;
public MyImage(String blob) {
this.blob = blob;
}
public static MyImage of(String value) {
return new MyImage(value);
}
}
和转换器
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;
}
}
将在保存时打印以下调试输出,我认为这是您想要的:
will print following debug output on save that I think is what you want:
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}}]}
尤其是图片部分.
这个的测试方法看起来像
Test method for this looks like
@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);
}
这篇关于Neo4j - 列表类型字段的自定义转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!