Spring Data Neo4J与嵌套对象的关系

时间:2013-09-25 21:04:24

标签: neo4j spring-data-neo4j

我想保存一个包含嵌套对象的关系实体(所以不是String,long,...)。当我在单元测试中保存并检索它时,除嵌套对象外,关系的所有属性都被填充。我也尝试添加@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;
...
}

2 个答案:

答案 0 :(得分:3)

您可以利用Spring类型转换系统Spring type conversion system在节点实体和关系实体中嵌入对象。 提供一对字符串到对象和对象到字符串转换器,并在Spring配置文件中声明它们。 以下是我在基于SDN的应用程序中成功使用的简单方案。对象扩展嵌入式公共接口,以方便地声明单个转换器并转换为/从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. 弹簧配置。

  4. 将以下行放在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>
    

答案 1 :(得分:0)

我不认为SDN可以持久化Object字段。来自文档:

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.

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