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

  • 相关阅读:
    ORACLE 查找数据库中有记录的表
    [原]Asp.Net 错误:无法连接到Asp.Net Developement server
    中国移动手机话费查询号码1008611
    动手修改VS2008的解决方案文件,以让VS2005打开它
    [转]飞秋使用说明与常见问题解决方法
    微软发布Fix it 修复Windows 7等系统0day漏洞
    Oracle DECODE 函数应用示例
    [转]C#实现访问网络共享文件夹
    c#保留小数点后位数的方法
    [转]微软紧急修复高危漏洞 30万网民PC已遭攻击
  • 原文地址:https://www.cnblogs.com/MrSi/p/8087090.html
Copyright © 2011-2022 走看看