0

我想保存一个包含嵌套对象的关系实体(所以不是字符串,长,...)。当我在单元测试中保存和检索它时,除了嵌套对象之外,关系的所有属性都被填充。我也尝试添加@fetch它,但这不起作用。 对于节点实体,这不是问题。在进一步调查中,节点实体也存在同样的问题。

spring-data-neo4j-examples 中的所有示例从不包含与嵌套对象的关系。是否支持?如果不是,解决我的域模型问题的最佳解决方案是什么?

请参见下面的代码:

@RelationshipEntity(type = "SEND_DOCUMENT")
public abstract class AbstractDocument implements Document {

@GraphId
private Long graphId;

@Indexed
private String documentId;

@Fetch
private StoredDocument storedDocument; //=> this one is always null

@StartNode
@Fetch
private Company fromCompany;

@EndNode
@Fetch
private Company toCompany;
...
}
4

2 回答 2

3

您可以利用 Spring 类型转换系统Spring type conversion system将对象嵌入节点实体和关系实体中。提供一对字符串到对象和对象到字符串的转换器,并在 Spring 配置文件中声明它们。以下是我在基于 SDN 的应用程序中成功使用的简单方案。对象扩展了Embedded公共接口以方便地声明单个转换器并转换为 JSON 字符串格式(这只是为了在探索图形节点属性时获得更好的可读性,您可以选择您喜欢的任何字符串格式)。

  1. 字符串到对象转换器:

    final class StringToEmbeddedConverterFactory implements ConverterFactory<String, Embedded> {
    
        @Override
        public <T extends Embedded> Converter<String, T> getConverter(Class<T> type) {
            return new StringToEmbeddedConverter(type);
        }
    
        private final class StringToEmbeddedConverter<S extends String, E extends Embedded> implements Converter<S, E> {
    
            private Class<E> embeddedType;
    
            public StringToEmbeddedConverter(Class<E> embeddedType) {
                this.embeddedType = embeddedType;
            }
    
            @Override
            public E convert(S source) {
                if (source != null) {
                    return (E) new Gson().fromJson(source, embeddedType);
                } else {
                    return null;
                }
            }
        }
    }
    
  2. 对象到字符串转换器:

     final class EmbeddedToStringConverterFactory implements ConverterFactory<Embedded, String> {
    
        @Override
        public <T extends String> Converter<Embedded, T> getConverter(Class<T> type) {
            return new EmbeddedToStringConverter(type);
        }
    
        private final class EmbeddedToStringConverter<E extends Embedded, S extends String> implements Converter<E, S> {
    
            private Class<S> stringType;
    
            public EmbeddedToStringConverter(Class<S> stringType) {
                this.stringType = stringType;
            }
    
            @Override
            public S convert(E source) {
                if (source != null) {
                    return (S) new Gson().toJson(source);
                } else {
                    return null;
                }
            }
        }
    }
    
  3. 弹簧配置。

在 Spring 配置文件中放入以下行来声明转换器工厂:

<!-- language: lang-xml -->
<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.example.EmbeddedToStringConverterFactory"/>
            <bean class="com.example.StringToEmbeddedConverterFactory"/>
        </list>
    </property>
</bean>
于 2013-09-26T15:08:20.563 回答
0

我不认为 SDN 可以保留对象字段。从文档中:

20.4.3 @GraphProperty: Optional annotation for property fields ... all fields that contain primitive values are persisted directly to the graph. All fields convertible to a String using the Spring conversion services will be stored as a string. Spring Data Neo4j includes a custom conversion factory that comes with converters for Enums and Dates. Transient fields are not persisted.

我认为至少你的对象字段必须是可序列化的,但很可能你还必须编写和注册一个进行反序列化的转换器。你也不需要@Fetch,因为只有关系是延迟加载的。

于 2013-09-26T08:44:09.953 回答