1.0jpa 2.0_JPA 2.1实体图–第1部分:命名实体图

1.0jpa 2.0

延迟加载通常是JPA 2.0的问题。 如果要使用FetchType.LAZY(默认)或FetchType.EAGER来加载关系,则必须在实体上进行定义,并且始终使用此模式。 仅当我们要始终加载关系时才使用FetchType.EAGER。 在几乎所有情况下都使用FetchType.LAZY来获得性能良好且可伸缩的应用程序。

但这并非没有缺点。 如果必须使用关系的元素,则需要确保在从数据库加载实体的事务中初始化该关系。 这可以通过使用特定的查询来完成,该查询从数据库中读取实体和所需的关系。 但这将导致用例特定的查询。 另一个选择是在您的业务代码中访问该关系,这将导致对每个关系的附加查询。 两种方法都不完美。

JPA 2.1实体图是一个更好的解决方案。 实体图的定义与查询无关,并且定义了要从数据库中获取哪些属性。 实体图可以用作访存图或负载图。 如果使用提取图,则仅由实体图指定的属性将被视为FetchType.EAGER。 所有其他属性将是惰性的。 如果使用负载图,则实体图未指定的所有属性将保留其默认提取类型。

让我们看看如何定义和使用实体图。

示例实体

在此示例中,我们将使用带有项目列表的订单,每个项目都有一个产品。 所有关系都是懒惰的。

订单实体:

@Entity
@Table(name = "purchaseOrder")
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode(value = "items", subgraph = "items"), subgraphs = @NamedSubgraph(name = "items", attributeNodes = @NamedAttributeNode("product")))
public class Order implements Serializable {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate String orderNumber;@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)private Set<OrderItem> items = new HashSet<OrderItem>();...

OrderItem实体:

@Entity
public class OrderItem implements Serializable
{@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate int quantity;@ManyToOneprivate Order order;@ManyToOne(fetch = FetchType.LAZY)private Product product;

产品实体:

@Entity
public class Product implements Serializable
{@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate String name;

命名实体图

命名实体图的定义由实体上的@NamedEntityGraph批注完成。 它定义了唯一的名称和已加载的属性列表( attributeNodes )。

以下示例显示了实体图“ graph.Order.items”的定义,该图将加载OrderOrderItem列表。

@Entity
@Table(name = "purchase_order")
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode("items"))
public class Order implements Serializable {...

现在我们已经定义了实体图,我们可以在查询中使用它。 因此,我们需要创建带有查询提示的Map,并将其设置为find或query方法调用上的附加参数。

以下代码段显示了如何在find语句中使用命名实体图作为获取图。

EntityGraph graph = this.em.getEntityGraph("graph.Order.items");Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);return this.em.find(Order.class, orderId, hints);

命名子图

我们使用实体图来定义Order实体的提取操作。 如果我们想对OrderItem实体执行相同的操作,则可以使用实体子图执行此操作。 命名子图的定义类似于命名实体图的定义,并且可以引用为attributeNode。

以下代码段显示了用于加载每个OrderItemProduct的子图的定义。 定义的实体图将获取包含所有OrderItem及其产品Order

@Entity
@Table(name = "purchase_order")
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode(value = "items", subgraph = "items"), subgraphs = @NamedSubgraph(name = "items", attributeNodes = @NamedAttributeNode("product")))
public class Order implements Serializable {

里面发生什么事了?

好的,从发展的角度来看,实体图很棒。 它们易于使用,我们不需要编写其他代码来避免延迟加载问题。 但是里面发生了什么? 有多少查询发送到数据库? 让我们看看Hibernate调试日志。

2014-03-22 21:56:08,285 DEBUG [org.hibernate.loader.plan.build.spi.LoadPlanTreePrinter] (pool-2-thread-1) LoadPlan(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - Returns - EntityReturnImpl(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order, querySpaceUid=<gen:0>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - CollectionAttributeFetchImpl(collection=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items, querySpaceUid=<gen:1>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items) - (collection element) CollectionFetchableElementEntityGraph(entity=blog.thoughts.on.java.jpa21.entity.graph.model.OrderItem, querySpaceUid=<gen:2>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items.<elements>) - EntityAttributeFetchImpl(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Product, querySpaceUid=<gen:3>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items.<elements>.product) - QuerySpaces - EntityQuerySpaceImpl(uid=<gen:0>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - SQL table alias mapping - order0_ - alias suffix - 0_ - suffixed key columns - {id1_2_0_} - JOIN (JoinDefinedByMetadata(items)) : <gen:0> -> <gen:1> - CollectionQuerySpaceImpl(uid=<gen:1>, collection=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items) - SQL table alias mapping - items1_ - alias suffix - 1_ - suffixed key columns - {order_id4_2_1_} - entity-element alias suffix - 2_ - 2_entity-element suffixed key columns - id1_0_2_ - JOIN (JoinDefinedByMetadata(elements)) : <gen:1> -> <gen:2> - EntityQuerySpaceImpl(uid=<gen:2>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.OrderItem) - SQL table alias mapping - items1_ - alias suffix - 2_ - suffixed key columns - {id1_0_2_} - JOIN (JoinDefinedByMetadata(product)) : <gen:2> -> <gen:3> - EntityQuerySpaceImpl(uid=<gen:3>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.Product) - SQL table alias mapping - product2_ - alias suffix - 3_ - suffixed key columns - {id1_1_3_} 2014-03-22 21:56:08,285 DEBUG [org.hibernate.loader.entity.plan.EntityLoader] (pool-2-thread-1) Static select for entity blog.thoughts.on.java.jpa21.entity.graph.model.Order [NONE:-1]: select order0_.id as id1_2_0_, order0_.orderNumber as orderNum2_2_0_, order0_.version as version3_2_0_, items1_.order_id as order_id4_2_1_, items1_.id as id1_0_1_, items1_.id as id1_0_2_, items1_.order_id as order_id4_0_2_, items1_.product_id as product_5_0_2_, items1_.quantity as quantity2_0_2_, items1_.version as version3_0_2_, product2_.id as id1_1_3_, product2_.name as name2_1_3_, product2_.version as version3_1_3_ from purchase_order order0_ left outer join OrderItem items1_ on order0_.id=items1_.order_id left outer join Product product2_ on items1_.product_id=product2_.id where order0_.id=?

日志显示仅创建了一个查询。 Hibernate使用实体图来创建具有所有3个实体( OrderOrderItemProduct )的加载计划,并通过一个查询加载它们。

结论

我们定义了一个实体图,该图告诉实体管理器从数据库中获取3个相关实体的图( OrderOrderItemProduct )。 实体图的定义和用法与查询无关,并且仅产生一条select语句。 因此,解决了JPA 2.0方法的主要缺点(在开头提到)。

从我的角度来看,新的实体图功能确实很棒,并且可能是解决延迟加载问题的好方法。 你怎么看待这件事?

翻译自: https://www.javacodegeeks.com/2014/05/jpa-2-1-entity-graph-part-1-named-entity-graphs.html

1.0jpa 2.0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Notion,程序员最后一款笔记软件

市面上笔记软件五花八门&#xff0c;都各有特色。wolai、语雀、飞书、印象笔记、石墨、幕布、为知笔记.....等等&#xff0c;数不胜数&#xff0c;但我最终选择了notion&#xff0c;因为它实在太好用了&#xff01;&#xff01;&#xff01;如果你之前没使用过&#xff0c;赶紧…

通过Main的Checkpoint Restore加快Java启动速度

Java虚拟机为已编译为字节码 &#xff08;但不一定是用Java编写&#xff09;的应用程序提供了托管运行时环境。 与为特定平台静态编译的代码相比&#xff0c;这为应用程序开发人员提供了许多好处&#xff0c;并且通常可以提高性能。 JVM通过垃圾回收器 &#xff08;GC&#xff…

notion常用快捷键

由于我自己的电脑是window10系统&#xff0c;我也就只整理window系统的快捷键。notion官网上有全部快捷键的教程&#xff0c;链接如下&#xff1a; https://www.notion.so/Learn-the-shortcuts-66e28cec810548c3a4061513126766b0 这篇博客来自于我的CSDN账号&#xff0c;里面…

“操作无法完成因为其中的文件夹或文件已在另一个程序中打开”解决办法

在windows系统中&#xff0c;我们经常会遇到这样一个问题&#xff1a;删除某一个文件或者文件夹&#xff0c;被提醒&#xff1a;操作无法完成&#xff0c;因为其中的文件夹或文件已在另一个程序中打开。 这个时候我们一般会先检查是否真的有程序或者文件打开了没有关闭&#xf…

带有AngularJS资源的Spring Rest Controller

Angularjs ngResource是用于与基于REST的服务进行交互的angularjs模块。 我最近在Spring MVC的一个小型项目中使用了它&#xff0c;并希望记录一个对我来说很好的配置。 该控制器在工厂中运行&#xff0c;它支持在Hotel实体上进行CRUD操作&#xff0c;并支持以下方法&#xff…

【CLion】如何编译运行单个文件 (C/C++ Single File Execution插件的使用)

如果你知道如何使用 C/C Single File Execution 插件但仍然无法找到运行按钮 请直接看第五张图片 一、 这里我首先新建了一个项目&#xff0c;名为Demo 又在项目文件夹内新建了一个代码文件&#xff0c;名为TestCode 二、 然后在 File - Settings - Plugins 中搜索 C/C Single…

使用Mocks进行需求驱动的软件开发

jmock作者撰写的有关模拟框架的优秀论文 。 本文写于18年前的2004年&#xff0c;但其中有许多构建可维护软件系统的技巧。 在这篇文章中&#xff0c;我将重点介绍本文中的关键思想&#xff0c;但建议您阅读本文&#xff0c;以获取有关模拟和编程实践的重要思想。 模拟对象是测…

W10关闭警告声音

点击电脑左下角的“开始”按钮 在开始菜单中点击打开“设置” 在设置窗口中点击“个性化” 在轻松使用界面左侧点击“主题” 接着在右侧找到并点击“声音” 在弹出的窗口中点击“声音方案”下面的方框 在弹出的列表中选择“无声”&#xff0c;点击底部的“应用”和…

Ubuntu常用快捷键

命令行中快捷键 Tab 自动补全 Ctrla 光标移动到开始位置 Ctrle 光标移动到最末尾 Ctrlk 删除此处至末尾的所有内容 Ctrlu 删除此处至开始的所有内容 参考 Ubuntu 快捷键命令_糖糖糖-豆的博客-CSDN博客_ubuntu命令行快捷键

camel 调用soap_使用Apache Camel通过soap添加WS-Security

camel 调用soapWS-Security&#xff08;Web服务安全性&#xff09;是一个协议&#xff0c;可让您保护自己的soap Web服务。 发出Soap请求的客户端必须在Soap标头中提供登录名和密码。 服务器接收到肥皂请求&#xff0c;检查凭据并验证请求是否正确。 使用Apache Camel&#xf…

Typora中插入分页符

由于typora基于html&#xff0c;插入分页符的方法&#xff08;在导出成PDF时生效&#xff09;&#xff1a; <div style"page-break-after:always"></div>

使用Spring Boot Actuator监视Java应用程序

朋友不允许朋友写用户身份验证。 厌倦了管理自己的用户&#xff1f; 立即尝试Okta的API和Java SDK。 在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 您是否曾与Spring Boot Actuator合作&#xff1f; 这是一个非常有用的库&#xff0c;可帮助您…

【sublime】 按 ctrl+shift+f没有反应(系统:win10+搜狗输入法)

系统&#xff1a; win10 输入法&#xff1a; 搜狗 问题&#xff1a; sublime 按 ctrlshiftf没有反应 原因&#xff1a; sumlime 中 ctrlshiftf 与搜狗繁简切换冲突 解决&#xff1a; A. 右击搜狗输入法状态栏&#xff08;就是那个小条条&#xff09;&#xff0c;选择属性设…

SublimeText3 ctrl+f打开搜索框后怎么关闭

按esc就可以退出了&#xff0c;点那个 find all也会退出

javaone_JavaOne 2014 –有关提交的一些初步分析

javaone这些天时间不多了。 并行发生的事情如此之多&#xff0c;当然&#xff0c;最重要的Java会议就是一切。 JavaOne 2014已经关闭了CfP门&#xff0c;投票正在进行中。 程序委员会几乎没有什么可以谈论的&#xff0c;但是去年跳过了这种分析之后&#xff0c;现在是我寻求许…

Sublime打开与关闭右侧缩略图

启动sublime text 3软件&#xff0c;如图所示&#xff1b; 发现右侧缩略图占据了太大的位置&#xff0c;瞬间感觉整个世界都不好了&#xff1b; 要想关闭这个缩略图&#xff0c;需要到菜单视图里面设置&#xff0c;首先点击菜单栏“view”——“hideMiniMap”&#xff1b;如图所…

Sublime Text 如何查看当前文件的编码格式?

打开preference->setting->输入下面代码 "show_encoding": true,"show_line_endings": true 此时保存该配置文件&#xff0c;就能够看到 sublime 最底下一行会显示文件编码格式了。以上的配置内容在 Perference → Setting─Default 都是 false 的。…

jaxb-xjc.jar_使用xjc在一秒钟内生成您的JAXB类

jaxb-xjc.jar由于JAXB是JDK的一部分&#xff0c;因此它是处理XML文档最常用的框架之一。 它提供了一种从XML文档检索数据并将其存储到Java类的简便方法。 因为几乎每个Java开发人员都已经使用过JAXB&#xff0c;所以我不会解释不同的JAXB批注。 相反&#xff0c;我将重点介绍一…

修改Typora默认的字体为好看秀美的中文字体“华康手札体“

一 下载并安装"华康手札体W5P"字体 &#xff08;1&#xff09;下载方式&#xff1a; 1. 方式一 http://www.downcc.com/font/341067.html2.百度云链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/125Hh-tqWOy1Ht-GvD_P2MQ 提取码&#xff1a;z6ka 复制…

测试Spring Boot有条件的合理方式

如果您或多或少有经验的Spring Boot用户&#xff0c;那么很幸运&#xff0c;在某些时候您可能需要遇到必须有条件地注入特定bean或配置的情况 。 它的机制是很好理解的 &#xff0c;但有时这样的测试条件下&#xff08;以及它们的组合&#xff09;可能会导致混乱。 在这篇文章中…