【问题标题】:Incomplete @NodeEntity loaded from database从数据库加载不完整的@NodeEntity
【发布时间】:2019-07-03 08:50:18
【问题描述】:

从“Neo4j 推荐”教程之一中,我下载并导入了产品目录数据集。我正在使用对象图映射创建一个 Spring Neo4j 项目。

现在我为ProductCategory 创建了一个@NodeEntity。为了快速验证是否一切正常,使用@PostConstruct 方法和ProductServiceCategoryService 从数据库中获取产品和类别。

我注意到的是,如果我查询产品,则获取产品的类别,然后该集合中的所有产品不包含所有产品,而只包含我开始查询的产品。

但是,如果我直接查询类别本身,它确实包含所有产品。

图模型如下:

我要查询的数据子集是:

Product 实体定义为:

@NodeEntity
  public class Product {

  @Id
  private String sku;
  private String name;

  @Relationship(type = "IN_CATEGORY")
  private Category category;

  @Convert(PriceConverter.class)
  private BigDecimal price;
}

Category 实体定义为:

@NodeEntity
public class Category {
  @Id @GeneratedValue
  private Long id;

  private String name;

  @Relationship(type = "PARENT_CATEGORY")
  private Category parent;

  @Relationship(type = "IN_CATEGORY", direction = Relationship.INCOMING)
  private Set<Product> products = new HashSet<>();
}

我创建了一个Repository 类。 如果我查询CategoryRepository' withcategoryRepository.findByName("Desks")` 并打印结果,该类别有三个产品,正如预期的那样。

如果我在ProductRepository 查询“高度可调节站立式办公桌”并打印其类别信息,则它是“办公桌”类别,但它只包含一个产品(高度可调节站立式办公桌)而不包含其他两个产品.

private void showInfo(final Category category) {
    System.out.printf("Name:%s%n", category.getName());
    System.out.printf("Parent: %s%n", category.getParent());
    System.out.printf("Products:%s%n", category.getProducts());
}

我原以为该套装会被懒惰地评估为全套产品。我需要强迫它这样做吗?其他节点何时加载到@NodeEntity,您如何确定某个节点的完整子图已加载?

编辑: 该文档包含以下引用:

对于图形到对象的映射,相关实体的自动传递加载取决于调用 Session.load() 时指定的水平深度。默认深度 1 表示将加载相关节点或关系实体并设置其属性,但不会填充其相关实体。

这表明应该使用会话对象来加载更多数据,但我不知道是哪个会话对象。

【问题讨论】:

    标签: java neo4j spring-data-neo4j neo4j-ogm


    【解决方案1】:

    您的分析是正确的。 Spring Data Neo4j(和底层 OGM)中的默认加载深度为 1。当您加载产品时,您将获得其类别,但不会获得其他产品,因为这些在图中距离原始产品有 2 个跃点。如果您想获取所有相关产品,我可以想到 2 种可能的方法。

    1. 从产品中获取产品类别后,使用其id查询类别存储库。这将返回该类别的产品列表。

    2. 将原始产品请求的查询深度设置为 2。默认的 Spring Data 存储库方法允许您指定查询深度。然后,这将在图中返回与该产品最多 2 跳的所有相关内容。

    加载实体的“完整图”只有一种方法,即设置查询深度为-1。如果您的图形模型不是特别密集,这可能对您有用。但是,它可能会在其他情况下导致性能问题。此外,此技术与仅加载域模型中存在的那些实体不兼容。换句话说,如果图表包含您不想要的节点和关系,将查询深度设置为 -1 将盲目地将所有这些包含在查询中,只是在返回与您的域匹配的那些之前再次丢弃它们。同样,根据您的域模型和底层图之间的匹配,这可能是也可能不是问题。

    详情请咨询https://neo4j.com/docs/ogm-manual/current/migration/#_performance_and_unlimited_load_depth

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 2011-08-05
      • 2020-04-18
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多