【问题标题】:Spring Data Neo4J Relationship with nested objectSpring Data Neo4J 与嵌套对象的关系
【发布时间】:2013-09-25 21:04:23
【问题描述】:

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

【问题讨论】:

    标签: neo4j spring-data-neo4j


    【解决方案1】:

    您可以利用 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>
    

    【讨论】:

      【解决方案2】:

      我不认为 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.

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-31
        • 1970-01-01
        • 2016-02-02
        • 2016-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多