当前位置: 首页 > 知识库问答 >
问题:

JPA EntityGraph如何允许在运行时选择实体图?

何高歌
2023-03-14

我看到过各种帖子描述JPA EntityGraph允许在运行时选择图表。我不完全清楚这指的是什么。

出于诚意和尊重,我想参考这篇有用的文章:https://www.baeldung.com/jpa-entity-graph.(大多数JPA用户可能已经看过了。)

文章引用-

EntityGgraph允许对我们想要检索的相关持久性字段进行分组,并允许我们在运行时选择图形类型。

并在结论部分再次巩固上述陈述。

在本文中,我们探讨了如何使用JPA实体图动态地获取实体及其关联。

这个决定是在运行时做出的,我们在运行时选择是否加载相关关联。

正如我们在文章(5.1)中所看到的,EntityGraphs使用注释定义如下-
5.1。用注释定义实体图

@NamedEntityGraph(
  name = "post-entity-graph",
  attributeNodes = {
    @NamedAttributeNode("subject"),
    @NamedAttributeNode("user"),
    @NamedAttributeNode("comments"),
  }
)
@Entity
public class Post {

    @OneToMany(mappedBy = "post")
    private List<Comment> comments = new ArrayList<>();
    
    //...
}

@NameEntityGgraph注释是在编译时定义的,我在这里没有看到任何运行时或动态的内容。

但在5.2中,实体图是使用api或编程方式定义的-
5.2。用JPA API定义实体图

 EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
 entityGraph.addAttributeNodes("subject");
 entityGraph.addAttributeNodes("user");

在5.2方法中,我看到可以使用一些逻辑动态选择节点。因此,这种方法被称为“动态获取”和“基于运行时”。还是我遗漏了什么,我还有更多需要理解的东西。

进一步研究6中给出的方法。使用实体图
例如:

EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);

都是编程的,因此可以在运行时更改,也就是说,它们可以说是动态的
但上面的文章中遗漏了一种方法,但这里提到了-https://www.baeldung.com/spring-data-jpa-named-entity-graphs,如下所示,似乎不符合动态标准。

public interface ItemRepository extends JpaRepository<Item, Long> {

    @EntityGraph(value = "Item.characteristics")
    Item findByName(String name);
}

那么,动态方法仅仅是指5.2风格,还是也意味着5.1风格。

共有1个答案

欧阳哲
2023-03-14

在Baeldung的文章中,第5节只讨论了定义一个图的各种方法,并没有太多地强调定义本身的动态/非动态性质。

在第5.1节中,图的定义是静态的,但是这一节只是关于如何定义一个图,然后在没有必要动态构建图的典型情况下使用这个图。这一节展示了用JOIN FETCH部分构建HQL/JPA-QL查询的旧方法的替代方法。

@NamedEntityGraph(
  name = "post-entity-graph",
  attributeNodes = {
    @NamedAttributeNode("subject"),
    @NamedAttributeNode("user"),
    @NamedAttributeNode("comments"),
  }
)
@Entity
public class Post {

    @OneToMany(mappedBy = "post")
    private List<Comment> comments = new ArrayList<>();
    
    //...
}

然后,第6节将告诉您如何以各种方式使用前面定义的实体图。

// Getting the "statically" defined graph (from annotation)
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");

// Then using the graph
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);

当然,您可以将第一行交换到第5.2节中演示的完全动态构建的图:

// Building the graph dynamically
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
entityGraph.addAttributeNodes("subject");
entityGraph.addAttributeNodes("user");


// Then using the graph
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);

在这两种情况下,都为查询提供EntityGraph对象。

 类似资料:
  • 我使用log4j2.9 我在log4j2.xml中配置了文件追加器。 我在Runtiime找不到任何如何选择appender的例子。 你能给我举个简单的例子吗?

  • 问题内容: 我正在使用带有注释的Spring Bean,并且需要在运行时选择其他实现。 例如,我需要Windows平台,我需要Linux平台。 目前,我只知道一种可怕的解决方案: 请考虑我仅使用注释,而不使用XML配置。 问题答案: 您可以将bean注入移动到配置中,如下所示: 或者,您可以使用配置文件和,然后用注释(如或)注释您的服务实现,并为您的应用程序提供此配置文件之一。

  • 问题内容: 我有这样的现有功能 该表有四列来存储整数值,我正在使用上述功能分别读取它们。 现在,我将其转换为Entity Framework。 但是上面的函数返回一个错误 输入的字符串格式不正确 因为它返回列名本身。 我不知道如何解决这个问题,因为我是EF的新手。 任何帮助,将不胜感激 谢谢 问题答案: 这可能有助于解决您的问题: 现在,该方法适用于动态输入方法参数。

  • 问题内容: 我正在用Swift编写我的第一个iOS应用程序(仅iPhone)。主应用程序视图应允许用户从相册中选择图像。 我找到了以下 ViewController.swift 示例代码: 并具有以下View Controller Scene- 但是,当我启动该应用程序时,仅显示黑屏。我做错了什么?我发现的另一个示例代码是在Objective-C中,这对我没有帮助。 问题答案: 如果只想让用户使用

  • 如何确保作业在运行时,不允许同时再次运行? 我们有一个BJ,它需要1个小时来处理提要和填充临时表。这个BJ的第一步是清除临时表并开始从Main store前表填充数据。 考虑一个场景,当BJ启动时(第一次运行),如果我们再次启动BJ,作为第一步的一部分,它将从临时表中删除内容。 那么,请建议我如何在第一次执行之前保留第二次执行?

  • 问题内容: 我有以下课程: 我想做的是确定应用程序已经运行时(即 未 在启动时)将哪个实施注入。 所以理想情况是这样的: 做到这一点的最佳方法是什么? 问题答案: 用和声明实现 然后将它们都注入并使用: