上篇博文《JPA数据懒加载LAZY和实时加载EAGER(二)》讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数据的。那么如果保证自己想要获取关联数据时,数据库会话session还存在呢?今天讲解一种方法,借助Spring提供的@Transactional注解来实现方法内部的操作在同一次数据库连接中执行。需要注意的是,使用@Transactional注解,必须要保证方法通过Spring组件解析方式处理,spring代理会为方法注入事务拦截逻辑。

   关于spring的事务实现原理,可以参考《Spring @Transactional工作原理

   一、为实体类ProcessBlock和Node添加一对多的关联关系。Set<Node>属性使用懒加载方式。下面给出代码。  

@Entity(name = "nbpm_processblock")
@NamedQuery(name = "ProcessBlock.findByName", query = "select p from nbpm_processblock p where p.name=?1")
public class ProcessBlock implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
long id;
@Column(name = "name")
String name;
@Column(name = "description")
String description;
String subClass;
@OneToMany(mappedBy = "processblock", cascade = CascadeType.ALL,fetch=FetchType.LAZY)
// @JoinColumn(name="processblock_id")
Set<Node> nodeSet = new HashSet<Node>();

 二、为查询方法添加事务注解

    @Transactional
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(ModelMap model,HttpSession session) {
//ProcessBlockRepository processBlock = ApplicationContextUtil.instance.getBean(ProcessBlockRepository.class);
//List<ProcessBlock> list = processBlock.findByName1("主干流程");
Map<String, Object> params = new HashMap<>();
params.put("name", "主干流程");
List<ProcessBlock> list = ApplicationContextUtil.instance.getJpaUtil().list(
"select u from simm.spring.entity.ProcessBlock u where u.name=:name", params, ProcessBlock.class);
System.out.println("准备获取懒加载数据");
Set<Node> nodes = list.get(0).getNodeSet();

  三、调试一下,查看调用情况

  1、测试代码先执行List<ProcessBlock>查询,之后输出"准备获取懒加载数据",最后查询第一条ProcessBlock对应的节点集合。通过执行日志很容易看出,懒加载的数据只有在后续的代码逻辑中被调用后,才会生成sql查询,在数据库中执行获取数据。

  

  2、先获取List<ProcessBlock>列表后,在来获取第一个ProcessBlock对象对应的节点集合。调试显示已经成功获取到数据。

   

  至此,测试完毕。用法很简单,但是关于spring事务的实现这块还是很有意思的,一次数据库连接在线程中通过ThreadLocal变量传递,其生命周期靠事务拦截器来控制。这个过程在ORM框架中应该是一种比较通用的思路,在Hibernate中如此,其他框架应该也是相差无几。感谢你的阅读,欢迎留言讨论交流!

JPA数据懒加载LAZY配合事务@Transactional使用(三)的更多相关文章

  1. JPA数据懒加载LAZY和实时加载EAGER(二)

    懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用.其目的是实现关联数据的选择性加载,懒加载是在属性被引用时,才生成查询语句,抽取相关联数据.而实时加载则是执行完主查询后,不管是否 ...

  2. JPA数据懒加载LAZY和实时加载EAGER(转)

    原文:https://www.cnblogs.com/MrSi/p/8081811.html 懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用.其目的是实现关联数据的选择性加载, ...

  3. JPA的懒加载

    JPA数据懒加载LAZY和实时加载EAGER(二)   懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用.其目的是实现关联数据的选择性加载,懒加载是在属性被引用时,才生成查询语句 ...

  4. iOS 开发——实用技术Swift篇&Swift 懒加载(lazy)

    Swift 懒加载(lazy) 在程序设计中,我们经常会使用 * 懒加载 * ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都 ...

  5. Swift中懒加载(lazy initialization)的实现

    Swift中是存在和OC一样的懒加载机制的,但是这方面国内的资料比较少,今天把搜索引擎换成了Bing后发现用Bing查英文\最新资料要比百度强上不少. 我们在OC中一般是这样实现懒加载初始化的: 1: ...

  6. Rest风格中关于JPA使用懒加载的坑

    公司最近使用的ORM框架是JPA实现产品使用的是hibernate,曾经看过一篇博客上面说的是如果团队里面没有一个精通hibernate的人,那么最好不要使用它,我现在是深刻的体会到了.但是使用什么框 ...

  7. 001_Chrome 76支持原生HTML 图片懒加载Lazy loading

    Table Of Content 什么是懒加载? 语法参数及使用方式? 有哪些特点? 与js有关的实践 什么是懒加载? 技术背景 Web应用需要经常向后台服务器请求资源(通过查询数据库,是非常耗时耗资 ...

  8. 黑马程序员-懒加载 lazy loading

    懒加载:延迟加载,当程序启动时不加载资源,当程序需要这些资源时再去加载.需要的时候再加载的一种方式,能够减少内存的占用,效率高.其本质是重写get方法. 背景:由于ios内存有限,如果我们一次性将所有 ...

  9. Swift - 懒加载(lazy initialization)

    Swift中是存在和OC一样的懒加载机制的,在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间 懒加载 格式: lazy var 变量: 类型 = { 创建变量代码 }() 懒 ...

随机推荐

  1. Java接口和抽象类的理解

    接口和抽象类的相同之处就是 都会有抽象方法 抽象方法就是一个没有方法体 等待继承的子类完成的方法 然而接口比较严格 它的方法必须是抽象方法且是公开的 抽象类 可以有自己的属性 和 实体方法 首相用面向 ...

  2. Servlet--HttpSession接口,HttpSessionContext接口,Cookie类

    HttpSession接口 定义 public interface HttpSession 这个接口被 Servlet 引擎用来实现在 HTTP 客户端和 HTTP 会话两者的关联.这种关联可能在多外 ...

  3. maven-assembly-plugin插件的使用方法

    一. Assembly 是什么意思? 二. maven-assembly-plugin是什么? 它是maven中针对打包任务而提供的标准插件. 三. maven-assembly-plugin插件的作 ...

  4. Tomcat xxx unbound

    从别的地方import的代码 .出现apache unbound 第一步:选中项目右键Build Path->Configure Build Path-->选中Tomcat 7.0 unb ...

  5. android activity传递实体类对象

    通过实现Parcelable接口序列化对象的步骤: 1.实现Parcelable接口.2.并且实现Parcelable接口的public void writeToParcel(Parcel dest, ...

  6. Unity DoTween 动画使用案例

    这边我就直接放一个标准的Dotween动画的使用demo吧. 这个案例满足应该可以完成你所想实现的几乎所有复杂动画. void PlayTween() { //set tween data float ...

  7. 模块dll和lib

    一.dll动态链接库 1.dll 没有 main 函数 2.不能直接执行,可以注入exe中让它间接执行.只有把它编译到应用程序中才可以. 3.编写dll 函数前加上 _declspec(dllexpo ...

  8. R语言的神奇之基于向量

    对于大多数需要来说,当我们需要计算两个向量相加时,我们需要分别对这两个向量的元素进行遍历,所以写起来非常的麻烦.下面看看R语言是如何实现的. 首先,将1:5赋予一个名为x的向量 > X<- ...

  9. python3操作socketserver

    socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.模块中,已经实现了一些可供使用的类. 在python3中,导入socketserver模块使用的命令: import s ...

  10. Perf工具

    前段时间Linux下用nmon监控程序的运行,发现CPU的使用率很高,系统态Sys的比例很高.程序的速度不是很快,怀疑和上面的原因有关. 分别使用perf record,perf report和top ...