zoukankan      html  css  js  c++  java
  • JPA数据懒加载LAZY配合事务@Transactional使用(三)

       上篇博文《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中如此,其他框架应该也是相差无几。感谢你的阅读,欢迎留言讨论交流!

  • 相关阅读:
    极光推送的设备唯一性标识 RegistrationID
    排行榜算法设计实现比较 排序树 平衡二叉树
    UCloud首尔机房整体热迁移是这样炼成的
    from appium import webdriver 使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium)
    客户续费模型 逻辑回归 分类器 AdaBoost
    推举算法 AdaBoost 哥德尔奖 Godel Prize
    基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
    Django’s cache framework
    随机森林算法预测法官判决
    时间特征正弦化
  • 原文地址:https://www.cnblogs.com/MrSi/p/8087090.html
Copyright © 2011-2022 走看看